【转】 SpringCloudAlibaba--02——nacos

【转】 SpringCloudAlibaba--02——nacos

SpringCloudAlibaba 实际上对SpringCloud 进行了扩展组件,能够完美整合到SpringCloud RPC 远程调用。

1、Nacos 分布式注册中心、分布式配置中心。SpringCloudEureka+Config 组合

2、目的是为了推广阿里云产品,如果使用SpringCloudAlibaba 最好使用阿里云的整个体系的对应的产品。

* Nacos 分布式注册与发现功能 | 分布式配置中心

产生背景:RPC 远程调用中,服务的url 的治理。

* 传统的RPC 远程调用存在哪些问题

1、超时的问题

2、安全的问题

3、服务与服务之间URL 地址管理

这样就造成服务与服务之间依赖关系非常大,URL 地址一但发生改变,还需要人工修改RPC 远程调用地址,这个管理地址是非常复杂的。

那么要想个办法动态的管理治理这个URL 地址,这样就可以实现对服务动态管理,注册与发现、本地负载均衡、容错等等。

方案:

  整个微服务架构中最为核心的肯定是 注册中心。不然都没法通讯。。。

  注册中心:实际就是存放微服务的地址信息,可以实现动态感知。

  注册中心包括:Dubbo(X)依赖Zookeeper、Eureka、Consuler、Nacos等,redis 也可以实现。

 

  注册中心是不会存接口方法名的,什么getUserById、getName什么的,是不会村的,只会村IP 地址+ 端口号

  原理实现:

    1、生产者启动时候,会把key(服务名称)+value(IP和端口号)注册到微服务的注册中心。--也肯会是一个集群,就是key一样,value不一样,是多个端口。

    2、注册存放服务地址的类型:key是唯一的,value是list集合、一个列表。Map<key,List(String)>  

    3、消费者去注册中心根据 服务名称查询服务地址列表(集合)

    4、消费者获取到集群列表后,采用负载均衡器选择一个RPC 远程调用

Nacos 介绍

  分布式服务注册与发现、分布式配置中心框架

  官网地址介绍:https://nacos.io/zh-cn/docs/what-is-nacos.html

* Nacos 环境搭建准备

nacos 可以安装linux、windows、mac 版本都可以安装

具体安装地址参考:https://nacos.io/zh-cn/docs/quick-start.html

在 0.版本选择处 选择下载版本,解压,这里选择的版本是1.1.4版本的,这个版本和springboot的版本会有冲突,所以版本不要瞎搞。

默认端口是:8848,也可以在/conf 目录下的application.properties 文件修改端口或其他配置

/bin 目录下:

  启动命令:cmd startup.cmd  或者双击startup.cmd运行文件。

      

  关闭服务器: cmd shutdown.cmd  或者双击shutdown.cmd运行文件。

* 测试服务注册与发现 

创建SpringBoot 项目,导入依赖:

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>

    <dependencies>
        <!--  springboot 整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
    </dependencies>

配置yml 文件配置nacos:

spring:
  application:
    ###服务的名称
    name: test-member
  cloud:
    nacos:
      discovery:
        ###nacos注册地址
        server-addr: 127.0.0.1:8848

写个接口,测试写个controller:

@RestController
public class MemberService {
    @Value("${server.port}")
    private String serverPort;

    /**
     * 会员服务提供的接口被订单服务调用
     *
     * @param userId
     * @return
     */
    @GetMapping("/getUser")
    public String getUser(Integer userId) {
        return "端口号为:" + serverPort;
    }
}

启动main方法:

@SpringBootApplication
public class AppSpringBoot {
    public static void main(String[] args) {
        SpringApplication.run(AppSpringBoot.class);
    }
}

注意:先启动本地的nacos,

然后浏览器访问 127.0.0.1:8848/nacos ,输入用户名密码就行了,默认都是 nacos

然后就可以看到:

 * 使用discoveryClient 从注册中心获取接口地址

创建一个子服务当作消费者,进行编写,

yml 配置文件:和提供者一样,修改端口号和服务名称:

spring:
  application:
    ###服务的名称
    name: test-order
  cloud:
    nacos:
      discovery:
        ###nacos注册地址
        server-addr: 127.0.0.1:8848
server:
  port: 8090

建个service 包,写个模拟的接口:

@RestController
public class OrderService {

    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LoadBalancer loadBalancer;

    /**
     * 订单服务调用到我们的会员服务接口
     *
     * @return
     */
    @RequestMapping("/orderToMember")
    public Object orderToMember() {
        // 1.根据服务名称从 注册中心获取集群列表地址
        List<ServiceInstance> instances =
                discoveryClient.getInstances("test-member");
        // 2.列表任意选择一个 实现本地rpc调用 rest 采用我们负载均衡的算法
        ServiceInstance srviceInstance = loadBalancer.getSingleAddres(instances);
        URI rpcMemberUrl = srviceInstance.getUri();
        String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);
        return "订单调用会员返回结果:" + result;
    }
    
}

创建main 方法启动类:

@SpringBootApplication
public class AppOrder {
    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

然后启动,查看浏览器,并新打一个浏览器窗口访问: http://127.0.0.1:8090/orderToMember  ip+端口号+接口名

* 手写本地负载均衡轮询算法 

模拟 根据访问次数,访问不同的服务器

先避免吧端口号写死,检查提供者的接口,

    @Value("${server.port}")
    private String serverPort;

这个代码,然后配置文件yml 中配置端口号

server:
  port: 8081

启动完提供者,把端口号改成8080,再次启动,模拟2 个的集群,查看服务列表

 集群模拟完成,开始撸码

建个包写个接口:LoadBalancer

public interface LoadBalancer {
    /**
     * 从注册中心集群列表中获取单个地址
     * @param serviceInstances
     * @return
     */
    ServiceInstance getSingleAddres(List<ServiceInstance> serviceInstances);
}

然后写个它的实现类:就是访问次数 模于 服务器数量 的值,就去访问第几个服务器

@Component
public class RotationLoadBalancer implements LoadBalancer {
    /**
     * 0:表示从0开始计数
     */
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public ServiceInstance getSingleAddres(List<ServiceInstance> serviceInstances) {
        int index = atomicInteger.incrementAndGet() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}

ok,然后在那个OrderService 的类里调用,因为这个是类是调用的服务提供者。

 

posted @ 2020-10-15 01:39  CLASSIC~W  阅读(164)  评论(0编辑  收藏  举报