• 微服务


    传统的接口实现:
    客户端 - 》 控制器A -》 服务1 -》 dao
    客户端 - 》 控制器B -》 服务2 -》 dao

    网关实现:
    客户端 - 》gateway - > 服务1/服务2 -》 dao

    gateway 好处
    1. 去掉控制器,将http请求无缝接入服务接口
    2. 统一出入参格式
    3. 统一异常规范
    4. 自动检测服务接口规范

    客户请求 -> gateway:9001 -> 服务1: 8081 | 服务2: 8082 | other: 808n
    具体的微服务IP 端口都不同 ,客户端就不用关心每个微服务的ip端口了,直接通过geteway访问即可(类似nginx网关路由)
    通过geteway的yml或.properties配置好映射关系,服务启动后自动会去eureka获取微服务

    在SpringCloud 全家桶中网关中提供Zuul 服务组件,后来升级为Gateway
    微服务网关有
        路由转发:根据请求的url中的特征匹配到具体微服务中
        权限控制:实现了GlobalFilter接口,请求的url中 可以对token进行验证
        过滤: 如特殊字段 字符的过滤 再做熔断提示
        服务限流:并发请求微服务的阈值
        黑白名单控制等


    一、准备
    创建网关工程 pom.xml 加入:
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    启动类配置
    @EurekaClient
    @SpringBootApplication
    @EnableDiscoveryClient
    public class GatewayApplication {
         public static void main(String[] args) {
             SpringApplication.run(GatewayApplication.class, args);
         }
     }
    1.1 :路由
    server:
        port: 8080
    spring:
        application:
            name: gateway
        devtools: // 热部署 修改自动重启 pom需要引入
            restart:
                enabled: true
        cloud:
            gateway:
                routes:
                   - id: service_name           # 微服务名
                  uri: https://127.0.0.1:8081 # 微服务uri
                  predicates:                # 匹配规则关键字
                     - Path=/**               # 任意字符都可以可以进行路由 routes中一些配置与zuul类似写法的区别
                routes:
                   - id: service_name
                   uri: https://127.0.0.1:8082
                   predicates:
                       - Path=/**
               discovery:                         # 开启服务名称转发 注:开启redis限流此处即可不需要
                   locator:
                       enabled: true            # true配置 访问前缀必须有微服务名称 否则 无法访问

    # 注册中心地址
    eureka:
        client:
            service-url:
                defaultZone: http://127.0.0.1:9091/eureka
        instance:
            instance-id: 127.0.0.1:9091  
            prefer-ip-address: true

    1.2 权限
        @Component
        class TokenFilter implements GlobalFilter, Ordered { // GlobalFilter内置的全局过滤器 , Ordered执行顺序级别(很多拦截器)
            @Override
            int getOrder() { return 1; } // 值越小越先执行
            @Override
            Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                 String token = exchange.getRequest().getQueryParams().getFirst("Authroization");
                 // 然后根据token结合业务做处理
            // 比如:拿token与jwt或redis 校验 或者只判断是否有token 如果有就放行给微服务去处理 都可以 一般不放行
            // 还有做的完善点的 专门启用一个鉴权客户端服务端工程,然后在鉴权服务端
        ...
            return chain.filter(exchange);
      }
       }

    1.3 限流
    令牌桶概念:匀速生产令牌 - > 令牌桶容量 - > user去消耗令牌
    以下用redis实现桶
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>
    spring:
        redis:
            host: 192.168.92.10
            port: 6379
            database: 0
        cloud:
            gateway:
                routes:
              - id: service_name
                   uri: lb://service_name
                   predicates:
             - Path=/serviceName/**
              filters:
          - RewritePath=/serviceName/(?<segment>.*), /${segment} # 由于服务名转发注掉 又想根据项目名访问
          - name: RequestRateLimiter # 拦截器 对上面routes进行拦截
          args:
            key-resolver: '#{@uriKeyResolver}'   # redis限流入口
            redis-rate-limiter.replenishRate: 1     # 令牌桶每1s 向令牌桶加一次令牌
            redis-rate-limiter.burstCapacity: 2     # 令牌桶每1s之内 最多访问2次

    // redis限流入口 

    @Bean
    public KeyResolver uriKeyResolver(){
      return new KeyResolver(){
        @Override
        public Mono<String> resolve(ServerWebExchange exchange){
          // 获得用户请求的地址 进行限流
          return Mono.just(exchange.getRequest().getRemoteAddress().getHostAddress()); // 监控远程请求地址
        }
      }
    }

    群交流(262200309)
  • 相关阅读:
    最终一致性解决实例
    分布式事务一致性方案
    分布式事务
    OSX
    JAVA
    Eclipse
    Activiti
    CentOS
    用Visual Studio 2015 编写 MASM 汇编程序(二)从头开发一个Win32汇编程序
    Oracle
  • 原文地址:https://www.cnblogs.com/webster1/p/12611513.html
Copyright © 2020-2023  润新知