服务治理——微服务

Nacos注册中心

  Nacos是目前国内企业中占比最多的注册中心组件。它是阿里巴巴的产品,目前已经加入SpringCloudAlibaba中。

  服务提供者将自己的信息包括ip端口,注册到注册中心上。服务调用者去注册中心订阅信息,注册中心就会把实例提供给服务调用者。提供服务的可能有多个实例,这里使用负载均衡(轮询,随机,hash)来选择合适的实例,然后再远程调用。

  服务提供者与注册中心之间还有一个心跳机制,如果有服务挂掉,注册中心就会在服务列表中将服务删掉,并且给服务调用者进行推送和变更。

准备工作步骤如下:

在linux操作系统中,创建一个naocs文件夹,然后在里面创建一个文件名称为:custom.env

文件里面的内容为:

PREFER_HOST_MODE=hostname
MODE=standalone
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=192.168.248.133
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=root
MYSQL_SERVICE_PASSWORD=123
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai

然后在linux系统下下载nacos镜像,之后进行部署。

部署的文件为:
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

服务注册

提供自己的信息到nacos

后端:

1.引入Nacos discovery依赖:

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2.配置Nacos地址:

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址

多实例部署,在配置一份实例部署,并且更改端口号,防止冲突

服务发现

调用者去注册中心拉去服务列表

要想调用服务是不知道该服务的地址的,因此必须去Nacos中拉去服务的信息。

负载均衡实现:

private final Discoveryclient discoveryclient;

private void handleCartItems(List<CartV0> vos){
//.根据服务名称,拉取服务的实例列表
List<ServiceInstance>instances = discoveryclient,getInstances("item-service");
//2.负载均衡,挑选一个实例
ServiceInstance instance = instances.get(RandomUtil,randomInt(instances.size()));
//3.获取实例的TP和端口
URI uri = instance.getUri();

这样就不需要记住IP的端口信息了,可以通过实例名来获取。如果有一个服务挂了,就不会被调用,服务回复也会被重新调用。

代码如图:

之前的远程调用为

实现效果:

OpenFeign

  我们利用Nacos实现了服务的治理,利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了。而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用,一会儿本地调用。因此,我们必须想办法改变远程调用的开发模式,让远程调用像本地方法调用一样简单。而这就要用到OpenFeign组件了。

其实远程调用的关键点就在于四个:

  • 请求方式

  • 请求路径

  • 请求参数

  • 返回值类型

所以,OpenFeign就利用SpringMVC的相关注解来声明上述4个参数,然后基于动态代理帮我们生成远程调用的代码,而无需我们手动再编写,非常方便。

OpenFeign已经被SpringCloud自动装配,实现起来非常简单。

1.引入依赖,包括负载均衡组件SpringCloudLoadBalancer(在老的版本里负载均衡用的Ribbon)

  <!--openFeign-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!--负载均衡器-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  </dependency>

2.在启动类上添加@EnableClients注解,来启动OpenFeign功能。

3.编写OpenFeign客户端

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

这里只需要声明接口,无需实现方法。接口中的几个关键信息:

  • @FeignClient("item-service") :声明服务名称

  • @GetMapping :声明请求方式

  • @GetMapping("/items") :声明请求路径

  • @RequestParam("ids") Collection<Long> ids :声明请求参数

  • List<ItemDTO> :返回值类型

有了上述信息,OpenFeign就可以利用动态代理帮我们实现这个方法,并且向http://item-service/items发送一个GET请求,携带ids为请求参数,并自动将返回值处理为List<ItemDTO>

我们只需要直接调用这个方法,即可实现远程调用了。

4.使用FeignClient,实现远程调用

List<ItemTO> items = itemClient.quertItemByIds(List.of(1,2,3));

连接池

OpenFeign发起请求用的是Client 每次调用都要重写创建连接,对性能不友好

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:

  • HttpURLConnection:默认实现,不支持连接池

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http

1.引入依赖

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

 2.开启连接池功能

feign:
  okhttp:
    enabled: true # 开启OKHttp功能

最佳使用方式

避免重复编码的办法就是抽取。不过这里有两种抽取思路:

  • 思路1:抽取到微服务之外的公共module

  • 思路2:每个微服务自己抽取一个module

  • 方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。​  

  •  方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。​    

 在运行之前还需要添加扫描包

  • 方式1:声明扫描包:@EnableFeginClients(basePackages = “”)

  • 方式2:声明要用的FeignClient:@EnableFeginClients(Clients = {UserClient.class})

日志输出

   

OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:

  • NONE:不记录任何日志信息,这是默认值。

  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间

  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息

  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。

接下来,要让日志级别生效,还需要配置这个类。有两种方式:

  • 局部生效:在某个FeignClient中配置,只对当前FeignClient生效

@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class)

  • 全局生效:在@EnableFeignClients中配置,针对所有FeignClient生效。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

 只有在调试的时候才需要配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值