系统定制开发将Nacos注册到springboot使用以及Feign实现服务调用

 

 哈喽~大家好,系统定制开发这篇来看看将注册到springboot使用以及Feign系统定制开发实现服务调用。

 

 🥇个人主页:             

🥈 系列专栏:       

🥉推荐专栏: 

 

目录


 

一、前前言

1、系统定制开发什么是服务治理

系统定制开发服务治理是架构中最核系统定制开发心最基本的模块。系统定制开发用于实现各个微服务的系统定制开发自动化注册与发现

服务注册:系统定制开发在服务治理中,系统定制开发都会构建一个注册中心,系统定制开发每个服务单元向注册中系统定制开发心登记自己提供服务的详细信息。系统定制开发并在注册中心形成一张系统定制开发服务的清单,系统定制开发服务注册中心需要以心系统定制开发跳的方式去监测清单中系统定制开发的服务是否可用,系统定制开发如果不可用,系统定制开发需要在服务清单中剔除系统定制开发不可用的服务。

服务发现:系统定制开发服务调用方向服务注册系统定制开发中心咨询服务,系统定制开发并获取所有服务的实例清单,系统定制开发实现对具体服务实例的访问。

 

 

系统定制开发通过上面的调用图会发现,除了微服务,还有一个组件是服务注册中心,它是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。注册中心一般包含如下几个功能:

2、服务发现

服务注册:保存服务提供者和服务调用者的信息

服务订阅:服务调用者订阅服务提供者的信息,注册中心向订阅者推送提供者的信息

3、服务配置

配置订阅:服务提供者和服务调用者订阅微服务相关的配置,配置下发:主动将配置推送给服务提供者和服务调用者

4、服务健康检测

检测服务提供者的健康情况,如果发现异常,执行服务剔除

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

从上面的介绍就可以看出,nacos的作用就是一个注册中心,用来管理注册上来的各个微服务。

 

二、前言

国内公司一般都推崇阿里巴巴的技术,比如注册中心,SpringCloudAlibaba也推出了一个名为Nacos的注册中心。

Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比前文介绍的Eureka功能更加丰富,在国内受欢迎程度较高。

1、安装 nacos

下载地址

GitHub主页:

GitHub的Release下载页:

下载后直接解压(中文路径)

注:Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。

2、启动 nacos

到安装的bin目录,打开cmd,输入指令

startup.cmd -m standalone

看到这个,启动成功

 

 

直接访问地址

账号与密码默认nacos

安装完成。

3、将服务注册到nacos

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。

主要差异在于:依赖不同、服务地址不同

在cloud-demo父工程的pom文件中的<dependencies>中引入SpringCloudAlibaba的依赖:

  1. <dependency>
  2.    <groupId>com.alibaba.cloud</groupId>
  3.    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  4.    <version>2.2.6.RELEASE</version>
  5.    <type>pom</type>
  6.    <scope>import</scope>
  7. </dependency>

然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:

  1. <dependency>
  2.    <groupId>com.alibaba.cloud</groupId>
  3.    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  4. </dependency>

注意:不要忘了注释掉eureka的依赖。

在主类上添加@EnableDiscoveryClient注解

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. @EnableFeignClients // 开启 feign
  4. @EntityScan("com.example")
  5. public class ShopOrderApplication {
  6.   public static void main(String[] args) {
  7.      SpringApplication.run(ShopOrderApplication.class);
  8.   }
  9.   // RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate
  10.   // 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
  11.   @Bean
  12.   @LoadBalanced
  13.   public RestTemplate restTemplate() {
  14.      return new RestTemplate();
  15.   }
  16. }

 

在user-service和order-service的application.yml中添加nacos地址:

  1. spring:
  2.  cloud:
  3.    nacos:
  4.      server-addr: localhost:8848

 

重启微服务后,登录nacos管理页面,可以看到微服务信息:

 

 

 

三、基于Ribbon实现负载均衡

1、负载均衡

Ribbon是Spring Cloud的一个组件, 它可以让我们使用一个注解就能轻松的搞定负载均衡

第1步:在RestTemplate 的生成方法上添加@LoadBalanced注解

  1. @Bean
  2. @LoadBalanced
  3. public RestTemplate restTemplate() {
  4.   return new RestTemplate();
  5. }
  1. @RestController
  2. @Slf4j
  3. public class OrderController {
  4.   @Autowired
  5.   private RestTemplate restTemplate;
  6.   @Autowired
  7.   private OrderService orderService;
  8.   @Autowired
  9.   private DiscoveryClient discoveryClient;
  10.   //下单
  11.   @RequestMapping("/order/prod/{pid}")
  12.   public Order order(@PathVariable("pid") Integer pid) {
  13.      log.info("接收到{}号商品的下单请求,接下来调用商品微服务查询此商品信息", pid);
  14. //     //调用商品微服务,查询商品信息
  15. //     Product product = restTemplate.getForObject( "http://localhost:8081/product/" + pid, Product.class);
  16.      //从nacos中获取服务地址
  17. //   ServiceInstance serviceInstance = discoveryClient.getInstances("service-product").get(0);
  18. //   String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();
  19. //   log.info(">>从nacos中获取到的微服务地址为:" + url);
  20. //
  21. //       //通过restTemplate调用商品微服务
  22. //   Product product = restTemplate.getForObject(
  23. //         "http://" + url + "/product/" + pid, Product.class);
  24. //   log.info(">>商品信息,查询结果:" + JSON.toJSONString(product));
  25. //   //自定义规则实现随机挑选服务
  26. //   List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
  27. //   int index = new Random().nextInt(instances.size());
  28. //   ServiceInstance serviceInstance = instances.get(index);
  29. //
  30. //   String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();
  31. //   log.info(">>从nacos中获取到的微服务地址为:" + url);
  32. //
  33. //       //通过restTemplate调用商品微服务
  34. //   Product product = restTemplate.getForObject("http://" + url + "/product/" + pid, Product.class);
  35.      log.info(">>客户下单,这时候要调用商品微服务查询商品信息");
  36.      //直接使用微服务名字, 从nacos中获取服务地址
  37.      String url = "service-product";
  38.        //通过restTemplate调用商品微服务
  39.      Product product = restTemplate.getForObject("http://" + url + "/product/" + pid, Product.class);
  40.      log.info("查询到{}号商品的信息,内容是:{}", pid, JSON.toJSONString(product));
  41.      //下单(创建订单)
  42.      Order order = new Order();
  43.      order.setUid(1);
  44.      order.setUsername("测试用户");
  45.      order.setPid(pid);
  46.      order.setPname(product.getPname());
  47.      order.setPprice(product.getPprice());
  48.      order.setNumber(1);
  49.      orderService.createOrder(order);
  50.      log.info("创建订单成功,订单信息为{}", JSON.toJSONString(order));
  51.     ;
  52.      return order;
  53.   }
  54. }

2、注解扩

  1. //@RestController
  2. // @RestController 是@controller和@ResponseBody 的结合
  3. // @Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。
  4. // @ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式返回给客户端
  5. // @Slf4j是用作日志输出的,一般会在项目每个类的开头加入该注解,如果不写下面这段代码,并且想用log
  6. // private final Logger logger = LoggerFactory.getLogger(当前类名.class);
  7. // 添加了该注释之后,就可以在代码中直接饮用log.info( ) 打印日志了

 

Ribbon支持的负载均衡策略

Ribbon内置了多种负载均衡策略,内部负载均衡的顶级接口

3、负载策略

com.netflix.loadbalancer.IRule , 具体的负载策略如下图所示

 

策略名策略描述实现说明
BestAvailableRule选择一个最小的并发请求的server逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas 时,使用roubine策略选择server。
RetryRule对选定的负载均衡策略机上重试机制。在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule轮询方式轮询选择 server轮询index,选择index对应位置的 server
RandomRule随机选择一个server在index上随机,选择index对应位置的server
ZoneAvoidanceRule复合判断server所在区域的性能和server 的可用性选择server使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server), AvailabilityPredicate用于过滤掉连接数过多的Server。

我们可以通过修改配置来调整Ribbon的负载均衡策略,具体代码如下

service-product: # 调用的提供者的名称 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

四、服务分级存储模型

一个服务可以有多个实例,例如我们的user-service,可以有:

  • 127.0.0.1:8081

  • 127.0.0.1:8082

  • 127.0.0.1:8083

假如这些实例分布于全国各地的不同机房,例如:

  • 127.0.0.1:8081,在上海机房

  • 127.0.0.1:8082,在上海机房

  • 127.0.0.1:8083,在杭州机房

Nacos就将同一机房内的实例 划分为一个集群

也就是说,user-service是服务,一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型,如图:

 

 

微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。杭州机房内的order-service应该优先访问同机房的user-service。

 

给user-service配置集群

修改user-service的application.yml文件,添加集群配置:

  1. spring:
  2. cloud:
  3.   nacos:
  4.     server-addr: localhost:8848
  5.     discovery:
  6.       cluster-name: SH # 集群名称

启动UserApplication,查看nacos控制台

 

 

修改负载均衡规则

修改order-service的application.yml文件,修改负载均衡规则:

  1. xuserservice:  
  2. ribbon:    
  3. NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

1、权重配置

实际部署中会出现这样的场景:

服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。

但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。

因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。

在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:

 

 

注意:如果权重修改为0,则该实例永远不会被访问

2、环境隔离

Nacos提供了namespace来实现环境隔离功能。

  • nacos中可以有多个namespace

  • namespace下可以有group、service等

  • 不同namespace之间相互隔离,例如不同namespace的服务互相不可见

 

在命名空间里面新建命名空间

 

点击确定

给微服务配置namespace只能通过修改配置来实现。

例如,修改order-service的application.yml文件:

  1. spring:
  2. cloud:
  3.   nacos:
  4.     server-addr: localhost:8848
  5.     discovery:
  6.       cluster-name: HZ
  7.       namespace: **** # 命名空间,填ID

重启服务后,访问控制台,可以看到下面的结果:

 

此时访问order-service,因为namespace不同,会导致找不到userservice,控制台会报错,这形成了环境隔离

 

五、Nacos与Eureka的区别

Nacos的服务实例分为两种类型:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。

  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

  • Nacos与eureka的共同点

    • 都支持服务注册和服务拉取

    • 都支持服务提供者心跳方式做健康检测

  • Nacos与Eureka的区别

    • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式

    • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除

    • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时

    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

 

六、基于实现服务调用

1、什么是Feign

Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。

Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果。

2、实现负载均衡

1、加入Fegin的依赖

  1. <!--fegin组件-->
  2. <dependency>
  3.    <groupId>org.springframework.cloud</groupId>
  4.    <artifactId>spring-cloud-starter-openfeign</artifactId>
  5. </dependency>

2、在主类上添加Fegin的注解 @EnableFeignClients   //开启Fegin

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. @EnableFeignClients//开启Fegin
  4. @EntityScan("com.example")
  5. public class ShopOrderApplication {
  6. 3、order工程里面创建一个service, 并使用Fegin实现微服务调用
  7. @FeignClient("service-product")//声明调用的提供者的name,在yam文件里面
  8. public interface ProductService {
  9.    //根据pid查询商品信息
  10.    @GetMapping(value = "/product/{pid}")
  11.    Product findByPid(@PathVariable("pid") Integer pid);
  12. }

4、修改controller代码,并启动验证

  1. package com.example.shoporder.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.example.shopcommon.domain.Order;
  4. import com.example.shopcommon.domain.Product;
  5. import com.example.shoporder.service.OrderService;
  6. import com.example.shoporder.service.ProductService;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.cloud.client.ServiceInstance;
  10. import org.springframework.cloud.client.discovery.DiscoveryClient;
  11. import org.springframework.web.bind.annotation.PathVariable;
  12. import org.springframework.web.bind.annotation.RequestMapping;
  13. import org.springframework.web.bind.annotation.RestController;
  14. import org.springframework.web.client.RestTemplate;
  15. import java.util.List;
  16. import java.util.Random;
  17. @RestController
  18. @Slf4j
  19. public class OrderController {
  20.   @Autowired
  21.   private RestTemplate restTemplate;
  22.   @Autowired
  23.   private OrderService orderService;
  24.   @Autowired
  25.   private DiscoveryClient discoveryClient;
  26.   @Autowired
  27.   private ProductService productService;
  28.   //下单
  29.   @RequestMapping("/order/prod/{pid}")
  30.   public Order order(@PathVariable("pid") Integer pid) {
  31.      log.info("接收到{}号商品的下单请求,接下来调用商品微服务查询此商品信息", pid);
  32.      log.info(">>客户下单,这时候要调用商品微服务查询商品信息");
  33.      
  34.      //通过fegin调用商品微服务
  35.      Product product = productService.findByPid(pid);
  36.      log.info("查询到{}号商品的信息,内容是:{}", pid, JSON.toJSONString(product));
  37.      //下单(创建订单)
  38.      Order order = new Order();
  39.      order.setUid(1);
  40.      order.setUsername("测试用户");
  41.      order.setPid(pid);
  42.      order.setPname(product.getPname());
  43.      order.setPprice(product.getPprice());
  44.      order.setNumber(1);
  45.      orderService.createOrder(order);
  46.      log.info("创建订单成功,订单信息为{}", JSON.toJSONString(order));
  47.      
  48.      return order;
  49.   }
  50. }

不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!

 

 

 

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发