app开发定制公司微服务学习笔记(二)Ribbon+OpenFeign+Gateway

文章目录

4 负载均衡

概述

app开发定制公司提供客户端的软件负载app开发定制公司均衡算法和服务调用

eureka-client已经自带ribbon

getForObject/postForObject:app开发定制公司获取数据转化成的对象,app开发定制公司可以理解为json

getForEntity/postForEntity:app开发定制公司获取响应头、http状态码、响应体

流程

策略

默认用RoundRobinRule

app开发定制公司轮询算法原理:restapp开发定制公司接口第几次请求数%服务器集群总数量=实际调用服务器位置下标,每次服务重启后rest接口计数从1开始

配置策略

  1. 代码方式(全局配置)

在@ComponentScan扫描不到的包定义新的策略(不要跟启动类放同一个包)

启动类添加@RibbonClient注解

@Beanpublic IRule randomRule() {    return new RandomRule();}
  • 1
  • 2
  • 3
  • 4
  1. 配置文件方式

可以根据服务名称具体配置

xxxservice: #服务名称  ribbon:    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  • 1
  • 2
  • 3

饥饿加载

Ribbon默认使用懒加载,第一次访问时创建对象,消耗时间较多

可以配置饥饿加载,项目启动时创建对象

ribbon:  eager-load:    enabled: true    clients:      - xxxservice
  • 1
  • 2
  • 3
  • 4
  • 5

与Nginx对比

  • Ribbon:在消费者端进行的负载均衡,进程内负载均衡

  • Nginx:接收了所有的请求进行负载均衡,集中式负载均衡

5 Open

RestTemplate调用的问题

  • 代码可读性差,编程体验不统一

  • 参数复杂url难以维护

与Feign对比

在Feign基础上加入对SpringMVC的支持

OpenFeign基本使用

一个声明式的http客户端

  1. 添加依赖
<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
  • 1
  • 2
  • 3
  • 4
  1. 启动类添加@EnableFeignClients注解

  2. 编写FeignClient接口

@FeignClient("userservice") //userservice为服务名称public interface UserClient {    @GetMapping("/user/{id}")    User findById(@PathVariable("id") Long id);}
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 使用FeignClient接口调用方法
//注入UserClientUser user = userClient.findById(id);
  • 1
  • 2

超时控制

Feign客户端默认等待1秒

ribbon:  ReadTimeout: 5000 #建立连接所用时间  ConnectTimeout: 5000 #从服务器读取到可用资源所用时间
  • 1
  • 2
  • 3

自定义配置


配置日志级别:

NONE-无日志

BASIC-仅记录请求方法、URL、响应状态码及执行时间

HEADERS-除了BASIC中定义的信息之外,还有请求和响应的头信息

FULL-除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据

  • 配置文件

    feign:  client:    config:      default: # default:全局配置,也可以使用服务名称        loggerLevel: FULL
    • 1
    • 2
    • 3
    • 4
    • 5
  • 代码

    @Configurationpublic class FeignClientConfig {    @Bean    public Logger.Level feignLoggerLevel() {        return Logger.Level.FULL;    }} //加在启动类代表全局配置@EnableFeignClients(defaultConfiguration = FeignClientConfig.class)//加在FeignClient接口代表单个服务配置@FeignClient(value = "userservice", configuration = FeignClientConfig.class)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

性能优化

  • 使用连接池(HttpClient, OKHttp)代替默认URLConnection

    <dependency>    <groupId>io.github.openfeign</groupId>    <artifactId>feign-httpclient</artifactId></dependency>
    • 1
    • 2
    • 3
    • 4
    feign:  httpclient:    enabled: true # 开关    max-connections: 200 # 最大连接数    max-connections-per-route: 50 # 每个路径的最大连接数
    • 1
    • 2
    • 3
    • 4
    • 5
  • 日志级别用BASIC或NONE

最佳实践

  • 给消费者的FeignClient和提供者的controller定义统一的父接口作为标准

  • 将FeignClient抽取为独立模块,把接口有关的实体类、默认Feign配置放到该模块,提供给所有消费者使用

    定义的FeignClient不在SpringBootApplication的扫描包范围,导致FeignClient无法注入spring容器,如何解决

  • 指定FeignClient所在包

    @EnableFeignClients(basePackages = "xxx")
    • 1
  • 指定FeignClient字节码

    @EnableFeignClients(clients = {UserClient.class})
    • 1

6 Gateway网关

网关功能

  • 身份认证、权限校验

  • 服务路由、负载均衡

  • 请求限流

技术实现

  • gateway:响应式编程(使用的Webflux的reactor-netty响应式编程组件,底层使用Netty通讯框架)

  • zuul:阻塞式编程

网关搭建

  1. 创建模块,引入依赖
<dependencies>    <!--网关-->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-gateway</artifactId>    </dependency>    <!--nacos服务注册发现-->    <dependency>        <groupId>com.alibaba.cloud</groupId>        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>        <version>2021.1</version>    </dependency></dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 配置

yml配置

server:  port: 10010spring:  application:    name: gateway  cloud:    nacos:      server-addr: localhost:8848 #nacos地址    gateway:      routes:        - id: user-service #路由标识,唯一          uri: lb://userservice #路由目标地址          predicates: #路由断言,判断请求是否符合规则            - Path=/user/** #路径断言,判断路径是否以/user开头
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

编码配置

@Configurationpublic class GatewayConfig {    @Bean    public RouteLocator routeLocator(RouteLocatorBuilder builder) {        RouteLocatorBuilder.Builder routes = builder.routes();        return routes.route("user-service", r -> r.path("/user/**").uri("lb://userservice")).build();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

路由断言工厂

作用:读取并解析配置的断言规则,转变为路由判断的条件

更多参考https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

时区时间点可以用ZonedDateTime类

过滤器

生命周期:pre(前置), post(后置)

种类:GatewayFilter, GlobalFilter

配置

作用:对进入网关的请求和微服务返回的响应做处理

过滤器工厂参考https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

server:  port: 10010spring:  application:    name: gateway  cloud:    nacos:      server-addr: localhost:8848 #nacos地址    gateway:      routes:        - id: user-service #路由标识,唯一          uri: lb://userservice #路由目标地址          predicates: #路由断言,判断请求是否符合规则            - Path=/user/** #路径断言,判断路径是否以/user开头          #filters:           # - AddRequestHeader=headerName,headerValue      # 也可以配置默认过滤器,使得所有路由都生效      default-filters:        - AddRequestHeader=headerName,headerValue
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

全局过滤器

以代码形式处理一切进入网关的请求和微服务响应

实现GlobalFilter接口,重写filter方法

//过滤器的顺序,值越小优先级越高@Order(0)@Componentpublic class AuthorizeFilter implements GlobalFilter {    @Override    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        ServerHttpRequest request = exchange.getRequest();        MultiValueMap<String, String> params = request.getQueryParams();        String authorization = params.getFirst("authorization");        if ("admin".equals(authorization)) {            return chain.filter(exchange);        }        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);        return exchange.getResponse().setComplete();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

过滤器链执行顺序

请求进入网关,会将路由过滤器、默认过滤器、全局过滤器合并到一个过滤器链,排序后依次执行每个过滤器

每个过滤器指定一个int类型的order值,值越小优先级越高

全局过滤器实现Ordered接口或添加@Order注解指定order值,路由过滤器、默认过滤器的order由Spring指定,按照声明顺序从1开始

如果order值一样,按照默认过滤器>路由过滤器>全局过滤器顺序执行

跨域配置

spring:    gateway:      globalcors: # 全局跨域处理        add-to-simple-url-handler-mapping: true # 解决options请求被拦截        corsConfigurations:          '[/**]':            allowedOrigins: # 允许哪些网站的跨域请求              - "xxx"            allowedMethods: # 允许跨域ajax请求方式              - "GET"              - "POST"            allowedHeaders: "*" # 允许在请求中携带的头信息            allowCredentials: true # 允许携带cookie            maxAge: 360000 # 跨域检测有效期(秒)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发