Not yet microservices? 5 minutes to teach you

Written in the front: This is a document on the topic of microservices, including the components commonly used in microservices. If you have any questions, you can find the answers you are looking for in the overall document.

Registration Center

Knowledge Index

  • What is a registry
  • cap theorem
  • Registry comparison
  • service registration
  • service call

1 What is a registry

When microservices call each other, they need to know the specific address of the called service and whether it is healthy (whether the server responds), which requires the registry to have these two capabilities: 1. The ability to allow service registration, 2. The ability to monitor services . If there is only one registry, our system cannot run normally when it cannot provide services for various reasons. Therefore, the registry is required to have the ability to cluster, and the data between clusters must be consistent. During failover of the host, the data of the master and slave nodes may be inconsistent, which may result in the incorrect service list being obtained when the service is called. Therefore, it must also have high availability and consistent cluster capabilities.

2 Spring Cloud supported registries and comparisons

2.1 cap theorem

CAP原则Also known as CAP定理, refers to in a distributed system, consistency ( Consistency), availability ( Availability), partition fault tolerance ( Partition tolerance). CAP 原则It means that these three elements can only achieve two points at most at the same time, and it is impossible to take care of all three.

Consistency 一致性: Whether all data backups have the same value at the same time. (equivalent to all nodes accessing the same latest copy of data)

Availability 可用性: Whether the cluster as a whole can still respond to the client's read and write requests after some nodes in the cluster fail. (High availability for data updates)

Partition Tolerance 容错性: In terms of practical effect, the partition is equivalent to the time limit for communication. If the system cannot achieve data consistency within the time limit, it means that a partition has occurred, and a choice must be made between C and A for the current operation.

CAP原则的精髓就是要么AP,要么CP,要么AC,但是不存在CAP。如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时C和P两要素具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足。

2.2 注册中心对比

Nacos Eureka Consul Zookeeper
一致性协议 CP+AP AP CP CP
健康检查 TCP/HTTP/MYSQL/Client Beat Client Beat TCP/HTTP/gRPC/Cmd Keep Alive
负载均衡策略 权重/metadata/Selector Ribbon Fabio
雪崩保护
自动注销实例 支持 支持 不支持 支持
访问协议 HTTP/DNS HTTP HTTP/DNS TCP
监听支持 支持 支持 支持 支持
多数据中心 支持 支持 支持 不支持
跨注册中心同步 支持 不支持 支持 不支持
SpringCloud集成 支持 支持 支持 支持
Dubbo集成 支持 不支持 不支持 支持
K8S集成 支持 不支持 支持 不支持

其中Eureka2.x版本已经宣布闭源,Nacos在后续Spring CloudAlibaba章节中会介绍,本篇我们主要通过Consul来演示注册中心的配置及使用。

3 Consul

3.1 Consul介绍

Consul HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等)。使用起来也较 为简单。Consul使用 Go 语言编写,因此具有天然可移植性(支持LinuxwindowsMac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

3.2 Consul安装(虚拟机模拟linux操作)

查看所有docker镜像

docker images
复制代码

image-20220313163055030

拉取Consul镜像

docker pull consul # 默认拉取latest
复制代码

image-20220313163509121

可以再次查看镜像已经存在Consul

image-20220313163723377

启动一个Consul容器

docker run -d -p 8500:8500 --restart=always --name=consul consul:latest agent -server -bootstrap -ui -node=1 -client='0.0.0.0'
复制代码

image-20220313163630168

查看启动的容器

image-20220313163841248

浏览器访问安装机器的8500端口

http://ip:8500
复制代码

跳转到如下页面说明安装成功

image-20220313163954348

4 服务注册

接下来我们开发一个简单的服务注册到注册中心。

4.1 创建maven项目

新建一个spring_cloud_demos项目并创建service_provider模块,目录结构如下

image-20220313164838582

4.2 引入依赖

在父项目中引入spring-boot-starter-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.7.RELEASE</version>
</parent>
复制代码

最终如下:

image-20220313171722960

在service_provider中引入Consul依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
复制代码

最终如下:

image-20220313171739413

4.3 配置文件

server:
  port: 8001 #服务端口
spring:
  application:
    name: service-provider #服务名
  cloud:
    consul:
      host: 192.168.184.128 #注册中心地址
      port: 8500 #注册中心端口
      discovery:
        service-name: ${spring.application.name} #注册中心中该服务的服务名
复制代码

4.4 编写代码

4.4.1 启动类

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProvicerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceProvicerApplication.class, args);
    }
}
复制代码

代码说明:

1:@EnableDiscoveryClient表示发现注册中心,向注册中心注册服务
2:@SpringBootApplication见springboot章节
复制代码

4.4.2 接口编写

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "hello!";
    }
}
复制代码

4.4.3 运行启动类

运行后控制台看到如下内容说明启动成功:

image-20220313174302721

同时查看注册中心页面中该服务已经注册成功

image-20220313174337673

5 服务调用

5.1 创建子模块service_consumer

image-20220313174441071

5.2 引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
复制代码

5.3 配置文件

server:
  port: 8001 #服务端口
spring:
  application:
    name: service-provider #服务名
  cloud:
    consul:
      host: 192.168.184.128 #注册中心地址
      port: 8500 #注册中心端口
      discovery:
        service-name: ${spring.application.name} #注册中心中该服务的服务名
        register: false #不注册到注册中心
复制代码

说明:

1:由于消费者不需要注册到注册中心,所以spring.cloud.consul.discovery.register为false
复制代码

5.4 编写代码

5.4.1 启动类

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@SpringBootApplication
public class ServiceConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
复制代码

代码说明:

1:注册一个RestTemplate到spring容器中以便使用
复制代码

5.4.2 接口编写

@RestController
@RequestMapping("/consumer")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/hello")
    public String hello(){
        //1、获取注册中心中注册的service-provider实例列表
        List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("service-provider");
        //2、获取实例
        ServiceInstance serviceInstance = serviceInstanceList.get(0);
        //3、根据实例的信息拼接的请求地址
        String url = serviceInstance.getUri()+ "/hello";
        //4、发送请求
        return restTemplate.getForObject(url,String.class);
    }
}
复制代码

代码说明:

1:DiscoveryClient用于获取注册中心中对应服务的实例
2:serviceInstance.getUri()表示实例中的地址包括ip端口
3:RestTemplate用于进行rest方式的http请求
复制代码

5.4.3 运行启动类并访问接口

浏览器访问

http://localhost:8002/consumer/hello
复制代码

可以看到

image-20220313175240280

说明我们已经成功通过consumer访问到了service_provider/hello接口并响应数据

Guess you like

Origin juejin.im/post/7079431913571614751