Spring Cloud -- 注册中心

362 阅读1分钟

在分布式架构中,所有的必须服务都先注册,然后服务间的调用通过注册中心获取到调用地址才能进行。

image.png

这种模式下,在部署的时候服务间不用关注的ip地址、端口信息,因为这些都可以通过注册中心获取到,大大方便了部署。

Eureka 注册中心

Eureka 是 Netflix 开发的服务发现组件,本身是一个基于 REST 的服务。Spring Cloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 Spring Cloud 的服务注册与发现,同时还提供了负载均衡、故障转移等能力。

创建一个maven项目,pom.xml如下

image.png

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.CHIV</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka</name>
    <description>spring cloud demo by eureka</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    <dependencies>
        <!--eureka-server 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

EurekaApplication 中增加@EnableEurekaServer注解

配置文件如下

server:
  port: 9000 #指定运行端口
spring:
  application:
    name: eureka-server #指定服务名称

eureka:
  instance:
    hostname: localhost #指定主机地址
  client:
    fetch-registry: false #指定是否要从注册中心获取服务(注册中心不需要开启)
    register-with-eureka: false #指定是否要注册到注册中心(注册中心不需要开启)
  server:
    enable-self-preservation: false #关闭保护模式

启动后,访问http://localhost:9000/可以浏览到注册中心的。

image.png

客户端注册

创建一个新的maven项目,将上方的pom文件的spring-cloud-starter-netflix-eureka-server 替换为spring-cloud-starter-netflix-eureka-client

配置文件

server:
  port: 8101
spring:
  application:
    name: test-eureka-client
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
#      注册中心地址
      defaultZone: http://localhost:9000/eureka/


入口文件增加@EnableEurekaClient注解,启动后就可以在注册中心,注册列表中看到了。

image.png

服务调用

Ribbon + RestTemplate 实现服务的调用。

当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。

服务提供者

pom.xml文件中添加web力能

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

application.yml 没有什么特别,就是把服务注册到注册中心就可以了。

server:
  port: 8101
spring:
  application:
    name: test-eureka-client
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
#      注册中心地址
      defaultZone: http://localhost:9000/eureka/

我们编写的接口一定是返回json格式的对象。

编写一个web接口,访问http://localhost:8101/person/list 可以返回[{"name":"小明"}]

@RestController
@RequestMapping("person")
public class PersonController {


    @GetMapping("list")
    public Object getList(){

        return "[{\"name\":\"小明\"}]";    }}

消费者

添加ribbon依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

application.yml中增加ribbon配置

# 服务提者名称
service-url: http://ribbon-copy
ribbon:
  ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)
  ReadTimeout: 3000 #服务请求处理超时时间(毫秒)
  OkToRetryOnAllOperations: true #对超时请求启用重试机制
  MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数
  MaxAutoRetries: 1 # 切换实例后重试最大次数
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法

配置RestTemplate

@Configuration
public class RibbonConfig {

    @Bean
    //启动ribbon均衡负载
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

编写测试接口

@RestController
@RequestMapping("test")
public class TestRibbonController {
    @Autowired
    RestTemplate restTemplate;
    @Value("${service-url}")
    String serviceUrl;
    @GetMapping("ribbon")
    public Object getList(){
        return restTemplate.getForEntity(serviceUrl+"/person/list",Object.class);
    }
}

启动后,访问http://localhost:8104/test/ribbon 就能看到 [{"name":"小明"}]