SpringCloud
实用
02
微服务框架,SpringCloud微服务架构,Nacos配置管理Feign远程调用Gateway服务网关,Nacos配置管理,统一配置管理配置热更新配置共享搭建Nacos集群,01,统一配置管理配置热更新配置共享搭建Nacos集群,Nacos配置管理,统一配置管理,数据库,数据库,读取配置,注册发现,配置更改热更新,读取配置,Nacos配置管理,统一配置管理,在Nacos中添加配置信息:,Nacos配置管理,统一配置管理,在弹出表单中填写配置信息:,Nacos配置管理,统一配置管理,配置获取的步骤如下:,读取本地配置文件application.yml,项目启动,创建spring容器,加载bean,读取nacos中配置文件,nacos地址,Nacos配置管理,统一配置管理,引入Nacos的配置管理客户端依赖:在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml:,com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config,spring:application:name:userservice#服务名称 profiles:active:dev#开发环境,这里是dev cloud:nacos:server-addr:localhost:8848#Nacos地址 config:file-extension:yaml#文件后缀名,Nacos配置管理,统一配置管理,我们在user-service中将pattern.dateformat这个属性注入到UserController中做测试:,RestControllerRequestMapping(/user)public class UserController/注入nacos中的配置属性 Value($pattern.dateformat)private String dateformat;/编写controller,通过日期格式化器来格式化现在时间并返回 GetMapping(now)public String now()return LocalDateTIME.now().format(DateTimeFormatter.ofPattern(dateformat);/.略,将配置交给Nacos管理的步骤在Nacos中添加配置文件在微服务中引入nacos的config依赖在微服务中添加bootstrap.yml,配置nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去nacos读取哪个文件,Nacos配置管理,统一配置管理配置热更新配置共享搭建Nacos集群,Nacos配置管理,配置自动刷新,Nacos中的配置文件变更后,微服务无需重启就可以感知。不过需要通过下面两种配置实现:方式一:在Value注入的变量所在类上添加注解RefreshScope,Nacos配置管理,配置自动刷新,Nacos中的配置文件变更后,微服务无需重启就可以感知。不过需要通过下面两种配置实现:方式二:使用ConfigurationProperties注解,ComponentDataConfigurationProperties(prefix=pattern)public class PatternProperties private String dateformat;,Nacos配置更改后,微服务可以实现热更新,方式:通过Value注解注入,结合RefreshScope来刷新通过ConfigurationProperties注入,自动刷新注意事项:不是所有的配置都适合放到配置中心,维护起来比较麻烦建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置,Nacos配置管理,统一配置管理配置热更新配置共享搭建Nacos集群,Nacos配置管理,多环境配置共享,微服务启动时会从nacos读取多个配置文件:spring.application.name-spring.profiles.active.yaml,例如:userservice-dev.yamlspring.application.name.yaml,例如:userservice.yaml无论profile如何变化,spring.application.name.yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件,本地配置,nacos中的配置,当前环境配置,Nacos配置管理,多服务共享配置,多种配置的优先级:服务名-profile.yaml 服务名称.yaml 本地配置,微服务会从nacos读取的配置文件:服务名-spring.profile.active.yaml,环境配置服务名.yaml,默认配置,多环境共享优先级:服务名-环境.yaml 服务名.yaml 本地配置,Nacos配置管理,统一配置管理配置热更新配置共享搭建Nacos集群,Nacos配置管理,Nacos集群搭建,Nacos生产环境下一定要部署为集群状态,部署方式参考课前资料中的文档:,Nacosnode1,Nacosnode2,Nacosnode3,Nginx,MySQL(主),MySQL(从),MySQL(从),nacosclient,集群搭建步骤:搭建MySQL集群并初始化数据库表下载解压nacos修改集群配置(节点信息)、数据库配置分别启动多个nacos节点nginx反向代理,Nacos配置管理,http客户端Feign,Feign替代RestTemplate自定义配置Feign使用优化最佳实践,02,Feign替代RestTemplate自定义配置Feign使用优化最佳实践,http客户端Feign,RestTemplate方式调用存在的问题,先来看我们以前利用RestTemplate发起远程调用的代码:存在下面的问题:代码可读性差,编程体验不统一参数复杂URL难以维护,String url=http:/userservice/user/+order.getUserId();User user=restTemplate.getForObject(url,User.class);,http客户端Feign,Feign的介绍,Feign是一个声明式的http客户端,官方地址:https:/,http客户端Feign,定义和使用Feign客户端,使用Feign的步骤如下:引入依赖:在order-service的启动类添加注解开启Feign的功能:,org.springframework.cloud spring-cloud-starter-openfeign,http客户端Feign,定义和使用Feign客户端,使用Feign的步骤如下:编写Feign客户端:主要是基于SpringMVC的注解来声明远程调用的信息,比如:服务名称:userservice请求方式:GET请求路径:/user/id请求参数:Long id返回值类型:User,FeignClient(userservice)public interface UserClient GetMapping(/user/id)User findById(PathVariable(id)Long id);,http客户端Feign,定义和使用Feign客户端,用Feign客户端代替RestTemplate,Feign的使用步骤引入依赖添加EnableFeignClients注解编写FeignClient接口使用FeignClient中定义的方法代替RestTemplate,http客户端Feign-快速入门,http客户端Feign,自定义Feign的配置,Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:一般我们需要配置的就是日志级别。,http客户端Feign,自定义Feign的配置,配置Feign日志有两种方式:方式一:配置文件方式全局生效:局部生效:,feign:client:config:default:#这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置 loggerLevel:FULL#日志级别,feign:client:config:userservice:#这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置 loggerLevel:FULL#日志级别,http客户端Feign,自定义Feign的配置,配置Feign日志的方式二:java代码方式,需要先声明一个Bean:而后如果是全局配置,则把它放到EnableFeignClients这个注解中:如果是局部配置,则把它放到FeignClient这个注解中:,public class DefaultFeignConfiguration Bean public Logger.Level feignLogLevel()return Logger.Level.BASIC;,EnableFeignClients(defaultConfiguration=DefaultFeignConfiguration.class),FeignClient(value=userservice,configuration=DefaultFeignConfiguration.class),Feign的日志配置:方式一是配置文件,feign.client.config.xxx.loggerLevel如果xxx是default则代表全局如果xxx是服务名称,例如userservice则代表某服务方式二是java代码配置Logger.Level这个Bean如果在EnableFeignClients注解声明则代表全局如果在FeignClient注解中声明则代表某服务,http客户端Feign-日志配置,http客户端Feign,Feign的性能优化,Feign底层的客户端实现:URLConnection:默认实现,不支持连接池Apache HttpClient:支持连接池OKHttp:支持连接池因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。,http客户端Feign,Feign的性能优化-连接池配置,Feign添加HttpClient的支持:引入依赖:配置连接池:,io.github.openfeign feign-httpclient,feign:client:config:default:#default全局的配置 loggerLevel:BASIC#日志级别,BASIC就是基本的请求和响应信息 httpclient:enabled:true#开启feign对HttpClient的支持 max-connections:200#最大的连接数 max-connections-per-route:50#每个路径的最大连接数,Feign的优化:使用HttpClient或OKHttp代替URLConnection引入feign-httpClient依赖配置文件开启httpClient功能,设置连接池参数日志级别生产环境尽量用basic,http客户端Feign-快速入门,http客户端Feign,Feign的最佳实践,方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。服务紧耦合父接口参数列表中的映射不会被继承,public interface UserAPI GetMapping(/user/id)User findById(PathVariable(id)Long id);,FeignClient(value=userservice)public interface UserClient extends UserAPI,RestControllerpublic class UserController implements UserAPI,public User findById(PathVariable(id)Long id)/.实现业务,http客户端Feign,Feign的最佳实践,方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用,feign-api,UserClient,DefaultConfig,User,order-service,引用依赖,远程调用,pay-service,UserClient,UserClient,.,Feign的最佳实践:让controller和FeignClient继承同一接口将FeignClient、POJO、Feign的默认配置都定义到一个项目中,供所有消费者使用,http客户端Feign-最佳实践,http客户端Feign,抽取FeignClient,实现最佳实践方式二的步骤如下:首先创建一个module,命名为feign-api,然后引入feign的starter依赖将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中在order-service中引入feign-api的依赖修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包重启测试,http客户端Feign,Feign的最佳实践,当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。有两种方式解决:方式一:指定FeignClient所在包方式二:指定FeignClient字节码,EnableFeignClients(basePackages=cn.itcast.feign.clients),EnableFeignClients(clients=UserClient.class),不同包的FeignClient的导入有两种方式:在EnableFeignClients注解中添加basePackages,指定FeignClient所在的包在EnableFeignClients注解中添加clients,指定具体FeignClient的字节码,http客户端Feign-最佳实践,统一网关Gateway,为什么需要网关gateway快速入门断言工厂过滤器工厂全局过滤器跨域问题,03,统一网关Gateway,为什么需要网关,数据库,数据库,注册发现,网关功能:身份认证和权限校验服务路由、负载均衡请求限流,读取配置,数据库,Feign,Feign,统一网关Gateway,网关的技术实现,在SpringCloud中网关的实现包括两种:gatewayzuulZuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。,网关的作用:对用户请求做身份认证、权限校验将用户请求路由到微服务,并实现负载均衡对用户请求做限流,统一网关Gateway,统一网关Gateway,搭建网关服务,搭建网关服务的步骤:创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:,org.springframework.cloud spring-cloud-starter-gateway com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery,统一网关Gateway,搭建网关服务,编写路由配置及nacos地址,server:port:10010#网关端口spring:application:name:gateway#服务名称 cloud:nacos:server-addr:localhost:8848#nacos地址 gateway:routes:#网关路由配置-id:user-service#路由id,自定义,只要唯一即可#uri:http:/127.0.0.1:8081#路由的目标地址 http就是固定地址 uri:lb:/userservice#路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates:#路由断言,也就是判断请求是否符合路由规则的条件-Path=/user/*#这个是按照路径匹配,只要以/user/开头就符合要求,统一网关Gateway,搭建网关服务,Gateway10010,userservice8081,userservice8082,orderservice8080,Nacos注册中心10086,服务注册和发现,http:/127.0.0.1:10010/user/1,routes:/user/*lb:/userservice-/order/*lb:/orderservice,1.路由规则判断,2.拉取服务列表,3.负载均衡,发送请求,http:/127.0.0.1:8082/user/1,网关搭建步骤:创建项目,引入nacos服务发现和gateway依赖配置application.yml,包括服务基本信息、nacos地址、路由路由配置包括:路由id:路由的唯一标示路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡路由断言(predicates):判断路由的规则,路由过滤器(filters):对请求或响应做处理,统一网关Gateway-搭建网关服务,统一网关Gateway,路由断言工厂Route Predicate Factory,网关路由可以配置的内容包括:路由id:路由唯一标示uri:路由目的地,支持lb和http两种predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地filters:路由过滤器,处理请求或响应,统一网关Gateway,路由断言工厂Route Predicate Factory,我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件例如Path=/user/*是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的像这样的断言工厂在SpringCloudGateway还有十几个,统一网关Gateway,路由断言工厂Route Predicate Factory,Spring提供了11种基本的Predicate工厂:,RoutePredicateFactory的作用是什么?读取用户定义的断言条件,对请求做出判断Path=/user/*是什么含义?路径是以/user开头的就认为是符合的,统一网关Gateway-路由断言工厂,统一网关Gateway,路由过滤器 GatewayFilter,GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:,网关Gateway,路由,过滤器,过滤器,过滤器,统一网关Gateway,过滤器工厂 GatewayFilterFactory,Spring提供了31种不同的路由过滤器工厂。例如:,过滤器工厂 GatewayFilterFactory,给所有进入userservice的请求添加一个请求头,给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器:,spring:cloud:gateway:routes:#网关路由配置-id:user-service uri:lb:/userservice predicates:-Path=/user/*filters:#过滤器-AddRequestHeader=Truth,Itcast is freaking awesome!#添加请求头,