美文网首页
Spring Cloud微服务体系的组成

Spring Cloud微服务体系的组成

作者: c_gentle | 来源:发表于2020-11-12 09:22 被阅读0次

    一、服务发现(Eureka/Consul/ZooKeeper)

    1、Eureka介绍

    Netflix Eureka是Spring Cloud服务注册发现的基础组件
    Eureka提供RESTful风格(HTTP协议)的服务注册与发现
    Eureka采用C/S架构,Spring Cloud内置客户端

    2、Eureka的组成

    Eureka的组成

    3、搭建Eureka注册中心

    启动Idea -> Spring Initializr 向导 
    组件向导选中 Spring Cloud Discovery -> Eureka Server
    SpringBoot版本选择 2.1.8
    Spring Boot 2.1.8 对应了Spring Cloud Greewich SR3 
    pom.xml确保引入
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    下载慢可以引入阿里云镜像仓库
    
        <repositories>
            <repository>
                <id>aliyun</id>
                <name>aliyun</name>
                <url>https://maven.aliyun.com/repository/public</url>
            </repository>
        </repositories>
    application.yml
    
    server:
      port: 8761 #端口
    eureka:
      server:
        enable-self-preservation: false #关闭自我保护
      instance: #设置注册中心应用名
        appname: provider-service#名称
        hostname: localhost#正式环境写域名
      client:
        service-url:
          defaultZone:
            http://localhost:8761/eureka/ #设置默认区域注册中心
        register-with-eureka: false #禁止自注册
        fetch-registry: false #是否注册中心获取其他微服务的注册信息
    EurekaServerApplication 增加@EnableEurekaServer注解启用Eureka服务器
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    
    }
    

    启用应用,访问 http://localhost:8761

    eurekaServer界面

    4、开发Eureka客户端(微服务)

    Eureka组成

    Eureka客户端开发要点
    maven依赖spring-cloud-starter-netflix-eureka-client application.yml
    配置eureka.client.service-url.defaultZone
    入口类增加@EnableEurekaClient

    创建新工程eureka-client
    启动Spring-Initialzr向导 ,
    选择
    Web -> Spring Web
    Spring Cloud Discovery -> Eureka Discovery Client 
    确认Spring Boot 版本为2.1.8
    pom.xml确保
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-web</artifactId>
           </dependency>
    
           <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
           </dependency>
    application.yml
    
    server:
     port: 80 #端口
    spring:
     application:
       name: order-service #微服务名称 必须全局唯一
    eureka:
     client:
       service-url:
         defaultZone:
           http://localhost:8761/eureka/ #注册中心地址
    入口类增加@EnableEurekaClient,启用Eureka客户端
    
    @SpringBootApplication
    @EnableEurekaClient
    public class EurekaClientApplication {
       public static void main(String[] args) {
           SpringApplication.run(EurekaClientApplication.class, args);
       }
    }
    

    先启动注册中心,在启动客户端,访问 localhost:8761查看eureka注册中心,看到客户端注册


    image.png

    5、Eureka名词概念与自我保护

    Eureka名词概念
    Register - 服务注册, 向Eureka进行注册登记
    Renew - 服务续约,30秒/次心跳包健康检查.90秒未收到剔除服务
    Fetch Registries - 获取服务注册列表,获取其他微服务地址
    Cancel - 服务下线, 某个微服务通知注册中心暂停服务
    Eviction - 服务剔除,90秒未续约,从服务注册表进行剔除
    Eureka自我保护机制
    Eureka在运行期去统计心跳失败率在15分钟之内是否低于 85%
    如果低于 85%,会将这些实例保护起来,让这些实例不会被剔除
    关闭自我保护:eureka.服务实例.
    enable-self-preservation: false
    PS: 如非网络特别不稳定,建议关闭

    6、Eureka高可用配置

    Eureka高可用配置

    Eureka高可用配置步骤
    服务提供者defaultZone指向其他的Eureka
    客户端添加所有Eureka 服务实例 URL

    Eureka只能绑定域名,在本地测试需要修改DNS配置文件hosts
    编辑 c:/windows/system32/drivers/etc/hosts
    # localhost name resolution is handled within DNS itself.
    #   127.0.0.1       localhost
    #   ::1             localhost
    127.0.0.1 server1
    127.0.0.1 server2
    127.0.0.1 server3
    高可用配置:
    
    application-p8761.yml
    
    启动项 Program arguments:--spring.profiles.active=8761
    
    server:
      port: 8761
    eureka:
      instance:
        appname: provider-service
        hostname: server1 #必须是域名
      client:
        service-url:
          defaultZone:
            http://server2:8762/eureka/,http://server3:8763/eureka/ #向其他注册中心节点注册
    application-p8762.yml
    
    启动项 Program arguments:--spring.profiles.active=8762
    
    server:
      port: 8762
    eureka:
      instance:
        appname: provider-service
        hostname: server2
      client:
        service-url:
          defaultZone:
            http://server1:8761/eureka/,http://server3:8763/eureka/ #向其他注册中心节点注册
    application-p8763.yml
    
    启动项 Program arguments:--spring.profiles.active=8763
    
    server:
      port: 8763
    eureka:
      instance:
        appname: provider-service
        hostname: server3
      client:
        service-url:
          defaultZone:
            http://server1:8761/eureka/,http://server2:8762/eureka/ #向其他注册中心节点注册
    入口类增加@EnableEurekaServer
    
    @SpringBootApplication
    @EnableEurekaServer
    public class HaEurekaServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(HaEurekaServerApplication.class, args);
        }
    }
    客户端指向所有Eureka注册中心节点
    
    server:
      port: 80
    spring:
      application:
        name: order-service
    eureka:
      client:
        service-url:
          defaultZone:
            http://server1:8761/eureka/,http://server1:8762/eureka/,http://server1:8763/eureka/
    

    7、Actuator监控组件

    Actuator自动为微服务创建一系列的用于监控的端点
    Actuator在SpringBoot自带,SpringCloud进行扩展
    pom.xml依赖spring-boot-starter-actuator


    Actuator监控端点

    二、服务间通信

    1、微服务之间调用的两种方式

    RestTemplate + @LoadBalanced 显式调用
    OpenFeign 隐藏微服务间通信细节

    2、Ribbon客户端负载均衡

    1.Ribbon是Netfilix开源的客户端负载均衡组件

    Ribbon是RestTemplate与OpenFeign的通信基础


    Ribbon执行过程

    2.Ribbon负载均衡策略

    Ribbon七种负载均衡模式
    ##在消费者中进行设置
    application.yml 针对某一个微服务设置负载均衡
    book-service: #微服务id
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机策略
    全局设置,全局设置优先级高于application.yml设置
    @SpringBootApplication
    @EnableEurekaClient
    public class MemberServiceApplication {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
        @Bean //全局负载均衡策略
        public IRule ribbonRule(){
            return new RoundRobinRule();
        }
        public static void main(String[] args) {
            SpringApplication.run(MemberServiceApplication.class, args);
        }
    }
    

    3、RestTemplate + @LoadBalanced 显式调用代码实现

    1.搭建eureka注册中心

    2.搭建客户端服务

    图书服务
    Spring Initializr
    Web->Eureka Discovery Client
    application.yml
    spring:
      application:
        name: book-service
    eureka:
      client:
        service-url:
          defaultZone:
            http://localhost:8761/eureka/
    BookController
    
        @GetMapping("/bsn")
        public Book findBySN(String sn, HttpServletRequest request){
            /*try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            Book book = null;
            if(sn.equals("1111")){
                book = new Book("1111", "测试图书1", String.valueOf(request.getLocalPort()));
            }else if(sn.equals("2222")){
                book = new Book("2222", "测试图书2", String.valueOf(request.getLocalPort()));
            }else if(sn.equals("3333")){
                book = new Book("3333", "测试图书3", String.valueOf(request.getLocalPort()));
            }
            return book;
        }
    启动两个服务,复制两个启动项,修改启动端口
    Program arguments: --server.port=8000
    Program arguments: --server.port=8001
    ![image.png](https://img.haomeiwen.com/i15616626/85a94565554a22ff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    

    3.搭建消费端服务

    RestTemplate介绍
    RestTemplate是Spring Cloud访问Restful API的请求对象
    RestTemplate与HttpClient、OKHttp职能类似
    @LoadBalanced注解
    @LoadBalanced是Ribbon提供的客户端负载均衡注解
    通常RestTemplate与@LoadBalanced联合使用
    创建订单服务
    Spring Initializr 
    web->Spring Web
    Spring Cloud Discovery -> Eureka Discover Client
    Spring Cloud Routing -> Ribbon
    确保pom.xml引入ribbon
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>
     appliaction.yml
    
    spring:
      application:
        name: member-service
    eureka:
      client:
        service-url:
          defaultZone:
            http://localhost:8761/eureka
    入口类注入RestTemplate
    
    @SpringBootApplication
    @EnableEurekaClient
    public class MemberServiceApplication {
        @Bean //注入
        @LoadBalanced //Ribbon负载均衡,默认轮询
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    业务开发,服务间通信
    
    @Controller
    public class MemberController {
        @Resource
        private RestTemplate restTemplate;
    
        @GetMapping("/borrow")
        @ResponseBody
        public String borrow(String sn){
            /*
                RestTemplate负载均衡格式要求:
                http://微服务id/webapi地址
            */
            Book book = restTemplate.getForObject("http://book-service/bsn?sn=" + sn, Book.class);#传入参数为返回值的实体类
            return book.getName() + ":" + book.getDesc() + "图书借阅成功";
        }
    }
    业务实体Book与JSON属性对应即可
    
    public class Book {
        private String sn;
        private String name;
        private String desc;
    
        public String getSn() {
            return sn;
        }
    
        public void setSn(String sn) {
            this.sn = sn;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    }
    

    4、OpenFeign服务间通信

    1.Feign与OpenFeign

    Feign是一个开源声明式WebService客户端,用于简化服务通信
    Feign采用“接口+注解”方式开发,屏蔽了网络通信的细节
    OpenFeign是SpringCloud对Feign的增强,支持Spring MVC注解

    2.使用openFeign进行服务间调用

    1.新建Spring boot Web项目,application name 为 product-service
    在pom.xml中引入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    spring-cloud-starter-alibaba-nacos-discovery作用为向Nacos server注册服务。
    spring-cloud-starter-openfeign作用为实现服务调用。
    2.修改application.yml配置文件

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
      application:
        name: product-service
    server:
      port: 8083
    

    3.在启动类上添加@EnableDiscoveryClient、@EnableFeignClients注解

    package com.example.productservice;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class ProductServiceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProductServiceApplication.class, args);
        }
    
    }
    

    4.编写OrderClient Interface
    注:/api/v1/order/test 会在下面order-service声明。
    OrderClient.java

    package com.example.productservice.client;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @Component
    @FeignClient("order-service")
    public interface OrderClient {
        @RequestMapping(method = RequestMethod.GET, value = "/api/v1/order/test")
        String callOrder();
    }
    

    5.编写Controller和service
    ProductController.java

    package com.example.productservice.controller;
    
    import com.example.productservice.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class ProductController {
        @Autowired
        ProductService productService;
    
        @RequestMapping(value = "testCallOrder", method = RequestMethod.GET)
        public String testCallOrder() {
            return productService.callOrder();
        }
    }
    

    ProductService.java

    package com.example.productservice.service;
    
    import com.example.productservice.client.OrderClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class ProductService {
    
        @Autowired
        OrderClient orderClient;
    
        public String callOrder() {
            String response = orderClient.callOrder();
            return response;
        }
    }
    

    3、OpenFeign工作原理

    image.png

    4、OpenFeign负载均衡策略

    OpenFeign负载均衡策略

    5、OpenFeign通信日志

    1.OpenFeign开启通信日志
    基于SpringBoot的logback输出,默认debug级别
    设置项:feign.client.config.微服务id.loggerLevel
    微服务id:default代表全局默认配置
    2.通信日志输出格式
    NONE: 不输出任何通信日志
    BASIC: 只包含URL、请求方法、状态码、执行时间
    HEADERS:在BASIC基础上,额外包含请求与响应头
    FULL:包含请求与响应内容最完整的信息
    3.OpenFeign日志配置项
    LoggerLevel开启通信日志
    ConnectionTimeout与ReadTimeout
    利用httpclient或okhttp发送请求

    6、替换OpenFeign通信组件

    1.OpenFeign通信组件
    OpenFeign基于JDK原生URLConnection提供Http通信
    OpenFeign支持Apache HttpClient与Square OkHttp
    SpringCloud按条件自动加载应用通信组件
    2.应用条件
    Maven引入feign-okhttp或者feign-httpclient依赖
    设置feign.[httpclient|okhttp].enabled=true

    7、OpenFeign多参数传递

    @FeignClient(name="book-service")
    public interface BookService {
        @GetMapping("/bsn")
        public Book findBySn
        (@RequestParam("sn") String sn,
        @RequestParam("p1") String p1,
        @RequestParam("p2") String p2);
    }
    //http://book-service/bsn?sn=...&p1=xxx&p2=xxx
    

    POST方式传递对象使用@RequestBody注解描述参数
    GET方式将对象转换为Map后利用@RequestParam注解描述

    三、熔断机制与Hystrix

    雪崩效应:服务雪崩效应产生与服务堆积在同一个线程池中,因为所有的请求都是同一个线程池进行处理,这时候如果在高并发情况下,所有的请求全部访问同一个接口,这时候可能会导致其他服务没有线程进行接受请求,这就是服务雪崩效应效应。
    服务熔断:熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,让后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。

    1、Hystrix介绍与工作原理

    1.Hystrix熔断器
    Hystrix(豪猪)是Netflix开源的熔断器组件,用于为微服务提供熔断机制预防雪崩,保护整体微服务架构的健康
    2.Hystrix功能
    预防微服务由于故障,请求长时间等待导致Web容器线程崩溃
    提供故障备选方案,通过回退(fallback)机制提供”服务降级”
    提供监控仪表盘,实时监控运行状态
    3.Hystrix 熔断器工作原理


    Hystrix 熔断器工作原理

    服务的健康状况 = 请求失败数 / 请求总数.
    熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.
    当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于
    设定阈值, 开关则切换为打开状态.
    当熔断器开关打开时, 请求被禁止通过.
    当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用
    成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.
    熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能.
    4.什么情况下会触发服务降级
    FAILURE: 执行失败,抛出异常
    TIMEOUT:执行超时(默认1秒)
    SHORT_CIRCUITED:熔断器状态为Open
    THREAD_POOL_REJECTED:线程池拒绝
    SEMAPHORE_REJECTED:信号量拒绝
    5.使用Hystrix步骤
    1.引入pom文件依赖

     <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            </dependency>
    
      2.在启动类上方写入@EnableHystrixDashboard
      3.在方法上@HystrixCommand
    
    public class MemberController {
        @Resource
        private RestTemplate restTemplate;
        @GetMapping("/snb")
        @ResponseBody
        /**
         * 模拟新书到货短信通知客户的业务
         */
        @HystrixCommand(fallbackMethod = "sendNewBookError")
        public String sendNewBook(String mobile,String bookname){
            String message = "[HOTBOOK]您预购的" + bookname + "已到货,明日将送到您府上";
            CallbackResult result = restTemplate.getForObject("http://message-service/sendsms?mobile=" +mobile+"&message=" + message , CallbackResult.class);
            if (result.getCode().equals("0")){
                return "短信已成功送达,服务返回:" +result.getResult();
            }else {
                return "短信发送失败,失败原因:" + result.getResult();
            }
        }
        public String sendNewBookError(String mobile,String bookname){
            return "短信发送失败,失败原因:消息服务无法正常运行,请稍后再试";
        }
    }
    

    6.OpenFeign与Hystrix整合
    OpenFeign中使用Hystrix
    OpenFeign内置Hystrix,feign.hystrix.enable开启即可
    feign: hystrix: enabled: true
    在@FeignClient增加fallback属性说明Fallback类
    @FeignClient(name="message-service",fallback = MessageServiceFallback.class) public interface MessageService { @GetMapping("/sendsms") public CallbackResult sendSMS(@RequestParam("mobile") String mobile , @RequestParam("message") String message); }
    Fallback类要实现相同接口,重写服务降级业务逻辑
    @Component public class MessageServiceFallback implements MessageService { @Override public CallbackResult sendSMS(String mobile, String message) { return new CallbackResult("INVALID_SERVICE","消息服务暂时无法使用,短信发送失败"); } }
    7.Hystrix超时设置

    超时设置
    Hystrix超时设置关系图
    eureka:
      client:
        service-url:
          defaultZone:
            http://localhost:8761/eureka
    spring:
      application:
        name: member-service
    feign:
      hystrix:
        enabled: true
      client:
        config:
          default:
            connectTimeout: 500
            readTimeout: 500  #(3000-2500)/3000=16.7% , (3000-500)/3000=83%
    hystrix:
      command:
        #"类名#方法名(参数类型1,参数类型2,参数类型n)"
        "MessageService#sendSMS(String,String)": #HystrixCommandKey
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 1000
                #假设:连接500毫秒,处理短信4000毫秒,哪个timeOut会触发服务降级
          circuitBreaker:
            forceOpen: false #true代表强制熔断器强制处于Open状态,即服务不可用
            requestVolumeThreshold: 50
            errorThresholdPercentage: 60
            sleepWindowInMilliseconds: 10000
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 6000
          circuitBreaker:
            #在当20秒的时间内,最近50次调用请求,请求错误率超过60%,则触发熔断10秒,期间快速失败。
            requestVolumeThreshold: 50
            errorThresholdPercentage: 60
            sleepWindowInMilliseconds: 10000
          metrics:
            rollingStats:
              timeInMilliseconds: 20000
    

    8.部署Hystrix Dashboard监控
    Hystrix Client依赖hystrix-metrics-event-stream
    Hystrix Client注册HystrixMetricsStreamServlet
    监控微服务依赖spring-cloud-starter-netflix-hystrix-dashboard
    监控微服务利用@EnableHystrixDashboard开启仪表盘
    9.Hystrix熔断设置
    产生熔断的条件:
    当一个Rolling Window(滑动窗口)的时间内(默认:10秒),最近20次调用请求,请求错误率超过50%,则触发熔断5秒,期间快速失败。
    TIPS: 如10秒内未累计到20次,则不会触发熔断
    Hystrix熔断设置项:


    Hystrix熔断设置项
    eureka:
      client:
        service-url:
          defaultZone:
            http://localhost:8761/eureka
    spring:
      application:
        name: member-service
    feign:
      hystrix:
        enabled: true
      client:
        config:
          default:
            connectTimeout: 500
            readTimeout: 500  #(3000-2500)/3000=16.7% , (3000-500)/3000=83%
    hystrix:
      command:
        #"类名#方法名(参数类型1,参数类型2,参数类型n)"
        "MessageService#sendSMS(String,String)": #HystrixCommandKey
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 1000
                #假设:连接500毫秒,处理短信4000毫秒,哪个timeOut会触发服务降级
          circuitBreaker:
            forceOpen: false #true代表强制熔断器强制处于Open状态,即服务不可用
            requestVolumeThreshold: 50
            errorThresholdPercentage: 60
            sleepWindowInMilliseconds: 10000
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 6000
          circuitBreaker:
            #在当20秒的时间内,最近50次调用请求,请求错误率超过60%,则触发熔断10秒,期间快速失败。
            requestVolumeThreshold: 50
            errorThresholdPercentage: 60
            sleepWindowInMilliseconds: 10000
          metrics:
            rollingStats:
              timeInMilliseconds: 20000
    

    四、API网关与Zuul

    一、初识API网关

    1.

    服务对外暴露
    通过网关隐藏后端服务

    2.使用网关的优点

    统一访问出入口,微服务对前台透明
    安全、过滤、流控等API管理功能
    易于监控、方便管理

    二、Spring Cloud API网关

    1、 API网关

    2、API网关产品

    Netflix Zuul
    Spring Cloud Gateway

    3、Netflix Zuul

    Zuul 是Netflix开源的一个API网关, 核心实现是Servlet
    Spring Cloud内置Zuul 1.x
    Zuul 1.x 核心实现是Servlet,采用同步方式通信
    Zuul 2.x 基于Netty Server,提供异步通信

    4、Netflix Zuul架构演化

    Netflix Zuul架构演化

    5、Netflix Zuul的功能

    认证和安全
    性能监测
    动态路由
    负载卸载
    静态资源处理
    压力测试

    6、Spring Cloud Gateway

    Spring Cloud Gateway,是Spring“亲儿子”
    Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式
    Gateway基于Spring 5.0与Spring WebFlux开发,采用Reactor响应式设计

    7、Netflix Zuul使用入门

    1.使用三部曲
    依赖spring-cloud-starter-netflix-zuul
    入口增加 @EnableZuulProxy
    application.yml 增加微服务映射
    2.微服务映射

    
    zuul:
      routes:
        book-service-api: #网关别名
          path: /bs/** #映射路径
          serviceId: book-service #微服务ID
    
        member-service-api:
          path: /ms/**
          serviceId: member-service
        ...
    

    8、Zuul负载均衡与服务降级

    Zuul负载均衡配置
    Spring Cloud Zuul内置Ribbon,与标准配置相同
    @Bean #全局配置
    public IRule ribbonRule(){
        return new RandomRule();
    }
    
    局部配置
    book-service: #目标微服务id
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    

    9、Zuul配置服务降级

    Spring Cloud Zuul内置Hystrix
    服务降级实现接口:FallbackProvider

    10、基于RateLimit实现网关限流

    1.微服务网关流量控制
    微服务网关是应用入口,必须对入口流量进行控制
    RateLimit是Spring Cloud Zuul的限流组件
    https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit
    RateLimit采用“令牌桶”算法实现限流
    2.什么是令牌桶

    令牌桶示意图
    3.RateLimit使用步骤
    依赖spring-cloud-zuul-ratelimit
    配置存储组件(关系数据库、redis、缓存...)
    配置限流策略

    11、Zuul的执行过程

    1.Zuul的执行过程


    Zuul的执行过程

    2.Http请求生命周期


    image.png
    3.Zuul内置过滤器
    image.png

    12、自定义过滤器

    1.需要实现ZuulFilter接口
    shouldFilter() - 是否启用该过滤器
    filterOrder() - 设置过滤器执行次序
    filterType() - 过滤器类型:pre|routing|post
    run() - 过滤逻辑
    2.Zuul内置过滤器


    Zuul内置过滤器

    3.Zuul+JWT跨域身份验证


    image.png
    4.自定义Zuul过滤器
    package com.itlaoqi.springcloud.zuul.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Component
    public class SecurityFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return "pre";
        }
    
        @Override
        public int filterOrder() {
            return 6;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            //从RequestContext获取上下文
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            String token = request.getHeader("token");
            if (token == null || token.trim().equals("")) {
                //对该请求禁止路由,也就是禁止访问下游服务
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(403);
                ctx.setResponseBody("{\"status\":403,\"message\":\"Token not found\"}");
                return null;
            }else{
                //校验Token正确性代码
                //...
                ctx.setSendZuulResponse(true);
                ctx.setResponseStatusCode(200);
                return null;
            }
        }
    }
    
    

    五、springCloud配置中心

    一、配置中心的分类

    1.Spring Cloud Config
    2.携程 Apollo
    3.阿里巴巴Nacos

    二、微服务改造步骤

    1.依赖"spring-cloud-starter-config"
    2.删除application.yml,新建bootstrap.yml
    3.配置"配置中心"服务地址与环境信息

    三、运行时刷新配置参数

    1、微服务依赖"spring-boot-starter-actuator";
    2、动态刷新类上增加@RefreshScope注解
    3、通过/actuator/refresh刷新配置

    四、Spring-Retry重试机制

    1、通过加入重试机制、提高应用启动的可靠性;
    2、重试触发条件1:配置中心无法与仓库正常通信
    3、重试触发条件2:微服务无法配置中心正常通信

    二、服务调用(Hystrix/Ribbon/OpenFeign)

    三、路由与过滤(Zuul/Spring Cloud Gateway)

    四、配置中心(Spring Cloud Config)

    五、消息总线(Spring Cloud Stream/Spring Cloud Bus)

    六、安全控制(Spring Cloud Security)

    七、链路监控(Spring Cloud Sleuth)

    八、其他工具(Spring Cloud Cli/Spring Cloud Cluster)

    相关文章

      网友评论

          本文标题:Spring Cloud微服务体系的组成

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