• 微服务nacos实战入门


    注册中心

    在微服务架构中,注册中心是最核心的基础服务之一

    主要涉及到三大角色:

    服务提供者 ---生产者

    服务消费者

    服务发现与注册

    它们之间的关系大致如下:

            1.各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。

            2.服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。

            3.各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。

            4.微服务网络地址发送变化(例如实例增加或IP变动等)时,会重新注册到注册中心。这样,服务消费者就无需人工修改提供者的网络地址了。

    nacos简介

    Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速

    实现动态服务发现、服务配置、服务元数据及流量管理。

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

    nacos实战入门

    安装

    下载win或linux版本

    Nacos 快速开始

    启动 

    win    

    startup.cmd -m standalone

    linux

    先进入解压的bin目录下

    sh startup.sh -m standalone

    访问

    http://localhost:8848/nacos

    默认账号密码都是 nacos

    基于 http://t.csdnimg.cn/iFbUc的继续配置

    快速回顾:

    上篇文章中 父级项目 demo01 子级 comm service 孙级 order product

                       comm 放置实体类 service 放置生产者和消费者

    1.service的pom文件引入依赖

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

    2.在主启动类上添加nacos的开启注解(Order消费者的启动类上)

    @EnableDiscoveryClient //  当前的微服务是可以被nacos发现的

    3. 在application.properties添加nacos的配置

    a.设置微服务的名字

    b.设置端口号

    c.添加到注册中心,将该服务交给注册中心去管理

    1. spring.application.name=order
    2. server.port=8081
    3. #设置注册中心的地址
    4. spring.cloud.nacos.discovery.server-addr=localhost:8848

    对product进行复制,命名product1

    完成如上配置后启动消费者与两个生产者

    服务调用的负载均衡

    什么是负载均衡

    通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上 进行执行。

    根据负载均衡发生位置的不同,一般分为服务端负载均衡和客户端负载均衡。

    服务端负载均衡指的是发生在服务提供者一方,比如常见的nginx负载均衡

    而客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求。

    负载均衡

    order 的pom引入依赖

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-loadbalancerartifactId>
    4. dependency>
    配置策略:
    1. package com.example.config;
    2. import org.springframework.cloud.client.ServiceInstance;
    3. import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
    4. import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
    5. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    6. import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.core.env.Environment;
    9. public class LoadBalancerConfig {
    10. @Bean
    11. ReactorLoadBalancer randomLoadBalancer(Environment environment,
    12. LoadBalancerClientFactory loadBalancerClientFactory) {
    13. String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); //loadbalancer.client.name
    14. // 对应的需要进行负载均衡的名字是什么
    15. System.out.println("======"+name);
    16. // product
    17. return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    18. }
    19. }
    使用策略:
    1. package com.order;
    2. import com.order.config.LoadBalancerConfig;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    6. import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
    7. import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
    8. import org.springframework.context.annotation.Bean;
    9. import org.springframework.web.client.RestTemplate;
    10. @SpringBootApplication
    11. @LoadBalancerClients(
    12. defaultConfiguration = LoadBalancerConfig.class
    13. // product 会使用这个策略
    14. // @LoadBalancerClient(value = "product",configuration= LoadBalancerConfig.class)
    15. )
    16. public class OrderAppliaction {
    17. public static void main(String[] args) {
    18. SpringApplication.run(OrderAppliaction.class);
    19. }
    20. @Bean
    21. // @LoadBalanced
    22. public RestTemplate getRestTemplate(){
    23. return new RestTemplate();
    24. }
    25. }

    四 基于Feign实现服务调用

    FeignClient和RestTemplate

    SpirngCloud 中,默认是使用HTTP进行微服务间通信,其中最常用的有两种实现形式

    • RestTemplate
    • Feign

    RestTempale

    • 其实在SpringWeb里面,已经原生支持了 RestTemplate,只不过我们一般使用的是把请求URL直接写死,而不是通过服务名的形式来调用,但是在微服务架构中,因为有了注册中心的存在,我们的负载均衡可以不需要使用第三方软件或者硬件实现了,所有,我们最佳的方式是经过服务名访问,请求到那个实例,由 负载均衡策略来替我们决定。
    • ribbion中的负载均衡策略了解

    Spring Cloud 中 7 种负载均衡策略!

    自定义策略(了解)

    第一种写法:

    直接使用 RestTemplate , Url写死

    第二种写法:

    拼接url的方式

    1. @Resource
    2. private LoadBalancerClient loadBalancerClient;
    3. @Override
    4. public boolean addOrder(Integer pid) {
    5. ServiceInstance choose = loadBalancerClient.choose("product");
    6. String requestMsg = "方式二 GET 请求 RibbonServer";
    7. String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/pro/t-product/findById/"+pid);
    8. TProduct forObject = restTemplate.getForObject(url, TProduct.class);
    9. System.out.println(forObject);
    10. //添加订单
    11. if(forObject.getKucun()>0){
    12. //添加订单
    13. TOrder oreder=new TOrder();
    14. oreder.setNum(1);
    15. oreder.setPid(pid);
    16. oreder.setUid(1);
    17. boolean save = this.save(oreder);
    18. return save;
    19. //oreder.se
    20. }
    21. return false;
    22. }

    利用 LoadBalancerClient 通过应用名获取 url,然后再使用 RestTemplate 请求

    使用DiscoveryClient拼接url

    1. @Resource
    2. private DiscoveryClient discoveryClient;
    3. @GetMapping("addOrder/{pid}")
    4. public Result addOrder(@PathVariable("pid") Integer pid){
    5. List<ServiceInstance> serviceId = discoveryClient.getInstances("product");
    6. //如果有俩相同的微服务 不能定死是第一个 不然就没有任何的意义
    7. //随机产生数字
    8. int i = new Random().nextInt(serviceId.size());
    9. System.out.println("服务******"+i);
    10. ServiceInstance instance = serviceId.get(i);
    11. // id username productname
    12. Order order=new Order();
    13. order.setId(1);
    14. order.setUsername("于永利");
    15. System.out.println("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid);
    16. //商品的名字
    17. Result result= restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid,Result.class);
    18. ObjectMapper objectMapper=new ObjectMapper();
    19. Product pro = objectMapper.convertValue(result.getT(), Product.class);
    20. //jackson
    21. //HashMap<String,String> product=(HashMap) result.getT();
    22. order.setProductname(pro.getName());
    23. return new Result(order);
    24. }

    第三种写法:

    使用OpenFeign

    OpenFeign默认的负载均衡规则是轮循

    修改pom文件
    1. <!--使用openFeign-->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-openfeign</artifactId>
    5. </dependency>
    启动类上开启注解

    @EnableFeignClients

    调用

    @FeignClient

    service接口:

    如果有异常 回滚到哪一个类里面

    1. @FeignClient(value="product",fallback = TOrderServiceImpl.class)
    2. public interface ITOrderService{
    3. }
    feign接口的实现类

    service的实现类

    1. @Service
    2. public class TOrderServiceImpl implements ITOrderService {
    3. @Override
    4. public TProduct addOrder(Integer pid) {
    5. System.out.println("你调用我了吗");
    6. if(pid==0){
    7. System.out.println("出错啦!!!!");
    8. }
    9. return null;
    10. }
    11. }

    使实现类生效

    加jar

    1. <!-- -->
    2. <dependency>
    3. <groupId>com.alibaba.cloud</groupId>
    4. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    5. </dependency>

    开启openfeign对sentinel的支持

    (在application.properties中编写)

    feign.sentinel.enabled=true

    正在赶工。。。

  • 相关阅读:
    html调用手机打电话、发短信网页源码/热门挪车自动拨打电话、发送短信html源码
    【http协议】Content-Type 超详细介绍
    debugger调试监听webpack配置文件的代码
    阿拉伯糖偶联核苷酸,UDP-b-L-arabinopyranose disodium salt,UDP-β-L-Ara.2Na
    设计模式--装饰器模式
    人大金仓分析型数据库JSON索引
    基于形状的匹配突破(黑中白,曙光,追赶visionpro)
    linux上mysql 8.0安装
    安卓循环遍历计时器
    每日一题——输入一个日期,输出它是该年的第几天
  • 原文地址:https://blog.csdn.net/Z15800020057/article/details/134402489