文章目录
4 负载均衡
概述
app开发定制公司提供客户端的软件负载app开发定制公司均衡算法和服务调用
eureka-client已经自带ribbon
getForObject/postForObject:app开发定制公司获取数据转化成的对象,app开发定制公司可以理解为json
getForEntity/postForEntity:app开发定制公司获取响应头、http状态码、响应体
流程
策略
默认用RoundRobinRule
app开发定制公司轮询算法原理:restapp开发定制公司接口第几次请求数%服务器集群总数量=实际调用服务器位置下标,每次服务重启后rest接口计数从1开始
配置策略
- 代码方式(全局配置)
在@ComponentScan扫描不到的包定义新的策略(不要跟启动类放同一个包)
启动类添加@RibbonClient注解
@Beanpublic IRule randomRule() { return new RandomRule();}
- 1
- 2
- 3
- 4
- 配置文件方式
可以根据服务名称具体配置
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客户端
- 添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
- 1
- 2
- 3
- 4
-
启动类添加@EnableFeignClients注解
-
编写FeignClient接口
@FeignClient("userservice") //userservice为服务名称public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id);}
- 1
- 2
- 3
- 4
- 5
- 使用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:阻塞式编程
网关搭建
- 创建模块,引入依赖
<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
- 配置
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