美文网首页
SpringCloud学习项目 —— 天气预报系统

SpringCloud学习项目 —— 天气预报系统

作者: 若琳丶 | 来源:发表于2019-10-10 00:08 被阅读0次

    一、项目实例

    1.1 项目列表

    • weather-eureka-server:Eureka 服务
    • weather-city-server-eureka:获取城市列表微服务
    • weather-data-server-eureka:获取某一城市天气数据微服务
    • weather-collection-server-eureka:定时任务获取天气信息微服务
    • weather-report-server-eureka:完整天气报告展示微服务
    • weather-eureka-zuul:API网关
    • weather-config-server:SpringCloudConfig 服务

    项目地址:https://github.com/midnight92/weather-spring-cloud

    1.2 依赖关系

    weather-city-server-eureka 与 weather-data-server-eureka为基础数据服务,他们是数据的来源。
    (在本案例中 weather-data-server-eureka 依赖于 weather-config-server 的配置,所以要先启动 weather-config-server,在启动 weather-data-server-eureka )
    weather-collection-server-eureka 依赖于 weather-city-server-eureka,因为它需要通过城市列表,来定时爬去某一城市的天气数据。
    weather-report-server-eureka 依赖于 weather-city-server-eureka 和 weather-data-server-eureka 和 weather-eureka-zuul,它需要 weather-city-server-eureka 获取城市列表,然后拿某一城市的 id,通过 weather-data-server-eureka 来获取天气数据。当然,首先通过 weather-eureka-zuul 分别路由到 weather-city-server-eureka 和 weather-data-server-eureka。

    部署顺序

    1. weather-eureka-server:Eureka 是基础
    2. weather-config-server:配置文件是最基础的发布的被依赖方
    3. weather-city-server-eureka:城市信息微服务,获取城市列表
    4. weather-collection-server-eureka:天气信息采集微服务(此模块可以不用部署,因为内容仅仅是http请求天气数据,并且保存到redis中。当前案例并没有实际使用 redis,所以可以忽略)
    5. weather-data-server-eureka:指定城市天气信息微服务
    6. weather-eureka-zuul:API 网关微服务
    7. weather-report-server-eureka:天气报告微服务

    二、微服务相关介绍

    2.1 一个项目的核心部分

    image.png
    • 表示层:连接客户端
    • 业务层:复杂的业务逻辑
    • 数据访问层:存放业务数据的持久性

    2.2 单一项目的缺点

    • 升级风险高:每次更新,不得不对整个系统做升级
    • 维护成本增加:
    • 可伸缩性变差:项目中有的服务压力大,有的服务压力小。压力大的需要的硬件支持就大,压力小的需要硬件支持就小。如果做机器的扩展,只能全部部署整个项目
    • 监控困难:

    2.3 SOA架构介绍

    面向服务架构

    2.4 微服务拆分原则

    思路:

    一个大的问题慢慢拆分成小的问题,逐个解决

    2.4.1 拆分足够小
    2.4.2 轻量级的通信
    2.4.3 领域驱动

    粗浅的理解就是单一的业务模型。订单业务是一个独立的领域,资金业务是一个独立的领域,票台业务是一个独立的领域,活动业务是一个独立的领域。
    每个服务都专注于某个领域,每个领域之间有各自的边界,不会混杂在一起。
    按照领域驱动来进行架构设计,可以保证系统的有逻辑边界

    2.4.4 单一职责
    2.4.5 DevOps?

    2.5 如何设计微服务系统

    • 服务拆分:确认好业务边界后的模块拆分
    • 服务注册:多个服务的注册表
    • 服务发现:从服务注册表中获取服务的信息
    • 服务消费:调用其他服务的过程
    • 统一入口:
    • 配置管理:所有服务共用一套配置信息
    • 熔断机制:请求处理不过来,如果所有请求全部处理,可能会造成系统崩溃。此时需要熔断机制
    image.png

    分析数据流向

    数据是驱动架构发展的核心

    image.png

    系统的通信设计

    • http
    • dubbo

    系统存储设计

    • Redis
    • Mysql

    三、SpringCloud实践

    3.1 服务注册和发现 —— Eureka 注册中心

    3.1.1 配置Eureka-server

    使用@EnableEurekaServer
    @SpringBootApplication
    @EnableEurekaServer
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    编写配置文件
    server.port=8761
    eureka.instance.hostname=localhost
    eureka.client.registerWithEureka=false
    eureka.client.fetchRegistry=false
    eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
    spring.freemarker.prefer-file-system-access=false
    eureka.server.enable-self-preservation=false
    

    注意:
    在application.yml中添加spring.freemarker.prefer-file-system-access: false
    spring.freemarker.prefer-file-system-access意为是否优先从文件系统加载template

    3.1.2 配置 Eureka-client

    使用@EnableDiscoveryClient
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    
    编写配置文件
    spring.application.name=weather-report-eureka
    eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
    feign.client.config.feignName.connect-timeout=5000
    feign.client.config.feignName.read-timeout=5000
    server.port=8021
    

    3.2 服务消费 —— Feign

    • 添加依赖
    • application.properties 中进行配置超时时间
    • 使用@EnableFeignClients
    • 创建客户端接口(专门访问某一服务的接口)
    • 业务代码中注入客户端接口
    添加依赖

    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

    在启动类上添加注解
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    创建客户端接口

    创建服务类:

    @FeignClient("weather-data-eureka")
    public interface WeatherDataClient {
    
        @RequestMapping("/weather/cityId/{cityId}")
        WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
    }
    
    • @FeignClient 中的值是 eureka 注册中心中服务的名称(需要调用的服务的application.name
    • @RequestMapping 中填写需要调用服务的目标 http 接口的地址
    配置过期时间
    feign.client.config.feignName.connect-timeout=5000
    feign.client.config.feignName.read-timeout=5000
    

    3.3 API网关

    3.3.1 API 网关的意义

    image.png

    可以通过不同的路径,路由到不同的微服务中去

    3.3.2 配置API网关 —— Zuul

    配置API网关以后的架构


    image.png
    添加依赖
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
    
    添加注解

    添加@EnableDiscoveryClient注解,Zuul 所在的模块同时也是一个 Eureka-Client,然后再添加@EnableZuulProxy注解。

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableZuulProxy
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
    配置文件
    spring.application.name=weather-eureka-zuul
    eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
    
    zuul.routes.city.path=/city/**
    zuul.routes.city.service-id=weather-city-server-eureka
    
    zuul.routes.data.path=/data/**
    zuul.routes.data.service-id=weather-data-server-eureka
    
    server.port=8011
    

    3.4 集中化配置 —— Spring Cloud Config

    文件名配置规则


    image.png
    • 问题1:配置文件的文件名称必须与 config-client 的 application.name 相同吗?
    • 问题2:一个config-client 想读取多个配置文件该咋办?
    • 问题3:config-server 启动后,访问 config-server 的 url 只能跟一个key 有关系吗?如果读取到所有的config内容?
    • 问题4:url格式就只能 http://#{config-server host name}:#{port}/#{key}/#{profile}

    http://localhost:8888/name/dev

    image.png

    3.5 熔断机制

    3.5.1 概念相关

    目的:

    • 停止接受新的业务请求,转而直接返回结果。慢慢消化正在执行的任务,慢慢释放资源
    • 保护系统,防止造成雪崩

    意义:

    • 保持系统稳定
    • 减少性能损耗:断路器直接返回简单响应结果,不占用额外资源
    • 及时响应

    熔断和降级的区别:
    相似性:

    • 目的一致,通过技术手段保护系统
    • 表现形式,都是使得客户端暂时不可用,都是默认的响应内容
    • 粒度一致,以服务的级别来设置的
      区别:
    • 触发条件不同
      服务熔断:一般是某个服务的故障引起的,一般是指下游服务。下游服务调用请求压力过大
      服务降级:一般是从整体的负荷来考虑的。上游服务调用过来的请求减少,当前服务无需提供这么多的实例,需要减少

    3.5.2 集成 Hystrix

    断路器设置在 weather-report-server-eureka 中

    1. 添加依赖
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'
    
    2. 添加注解

    在启动类上添加注解,相当于打开了 hystrix 的开关

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableCircuitBreaker
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
    3. 设置fallback接口

    定义fallback类,并在 Feign 的接口中进行设置
    3.1 定义fallback类

    @Service
    public class DataClientFallback implements DataClient {
        @Override
        public List<City> cityList() {
            City city = new City();
            city.setCityId("101280601");
            city.setCityName("深圳");
            return Lists.newArrayList(city);
        }
    
        @Override
        public WeatherResponse getDataByCityId(String cityId) {
            return null;
        }
    }
    

    3.2 在 Feign 的接口中进行设置

    @FeignClient(name = "weather-eureka-zuul", fallback = DataClientFallback.class)
    public interface DataClient {
    
        @RequestMapping("/city/cities")
        List<City> cityList();
    
        @RequestMapping("/data/weather/cityId/{cityId}")
        WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
    }
    

    3.3 设置 application.properties 文件
    由于词用法是在 Feign 上添加的熔断器处理类,所以配置文件应该开启 Feign 对 Hystrix 的可用开关。

    feign.hystrix.enabled=true
    

    相关文章

      网友评论

          本文标题:SpringCloud学习项目 —— 天气预报系统

          本文链接:https://www.haomeiwen.com/subject/gawnpctx.html