服务注册nacos和OpenFerign(用于封装跨服务之间的调用方法)
服务注册和发现
注册中心原理
在微服务远程调用的过程中,包括两个角色:
- 服务提供者:提供接口供其它微服务访问,比如
item-service
- 服务消费者:调用其它微服务提供的接口,比如
cart-service
在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下:
Nacos注册中心
利用nacos实现服务的治理,利用RestTemplate实现了服务的远程调用。
但是远程调用的代码太复杂了,而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用,一会儿本地调用。
因此,我们必须想办法改变远程调用的开发模式,让远程调用像本地方法调用一样简单。而这就要用到OpenFeign组件了。
其实远程调用的关键点就在于四个:
- 请求方式
- 请求路径
- 请求参数
- 返回值类型
OpenFeign
用于封装跨微服务之间的调用的方法,不用每次都手动写发现微服务列表+负载均衡+请求发送。
在cart-service服务的pom.xml中引入OpenFeign的依赖和loadBalancer依赖时,注意关闭离线模式。
feign替我们完成了服务拉取、负载均衡、发送http请求的所有工作,是不是看起来优雅多了。
此时,就不需要RestTemplate(远程调用)了,还省去了RestTemplate的注册。
连接池
连接池指的是一组预先创建的 HTTP 连接,这些连接可以被重复使用,而不是每次请求都创建一个新的连接。
在 Feign 中,不同的 HTTP 客户端实现对连接池的支持有所不同:
- HttpURLConnection:这是 Java 的默认 HTTP 客户端实现,不支持连接池。每次请求都会创建一个新的连接,请求完成后连接会被关闭。这种方式在高并发场景下性能较差。
- Apache HttpClient:这是一个功能强大的 HTTP 客户端库,支持连接池。通过配置连接池,可以复用连接,提高性能。
- OKHttp:这是另一个流行的 HTTP 客户端库,也支持连接池。OKHttp 的连接池实现高效且易于配置,适合在高并发场景下使用。
按 Ctrl+Shift+N(Windows/Linux)或 Cmd+Shift+O(macOS),打开“查找文件”对话框。输入类名 FeignBlockingLoadBalancerClient,选择并打开该类文件。打开类文件后,按 Ctrl+F(Windows/Linux)或 Cmd+F(macOS)在该类中搜索 execute 方法,或者你可以直接按 Ctrl+Shift+F(全局搜索)来搜索整个项目中的 execute 方法。
抽取
如果拆分了交易微服务(trade-service),它也需要远程调用item-service中的根据id批量查询商品功能。这个需求与cart-service中是一样的。
因此,我们就需要在trade-service中再次定义ItemClient接口,这不是重复编码吗? 有什么办法能加避免重复编码呢?
避免重复编码的办法就是抽取。不过这里有两种抽取思路:
- 思路1:抽取到微服务之外的公共module
- 思路2:每个微服务自己抽取一个module
方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。
方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。
抽取之后一直报这个错:
解决:
在cart-service的启动类上添加声明即可,两种方式:
方式一:声明扫描包:(我采用的)
方式二:声明要用的FeignClient
日志配置
OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
在hm-api模块下新建一个配置类,定义Feign的日志级别:
该配置类不用加Configuration注解:
在cart-service
中的启动类上已经配置了@EnableFeignClients(basePackages = "com.hmall.api.client"
。
在该配置类中, defaultConfiguration = DefaultFeignConfig.class)
,启动的时候会自动注入该配置类