一篇文章概括Spring Cloud微服务教程(下篇)

2022-03-10 13:41:16 浏览数 (1)

在前面教程中,我们概括了进行微服务业务开发时需要的三个基础功能:注册服务器、断路器和Feign客户端,有了这三个组件,你基本可以在本地进行微服务开发,但是在正式Spring Cloud生产环境中,还需要配置服务器,这样可以实现动态配置管理,同时需要类似Nginx这样网关路由器Zuul或Spring Cloud Gateway,这两个组件是生产运行配置方面:

1. Spring Cloud Bus

如何将配置推送到分布式微服务节点?本上我在生产中看到了以下解决方案:

  • 使用分布式缓存(Hazelcast,Oracle Coherence ...)
  • 通过JMS或AMPQ等中间件推送设置。

Spring Cloud中的一个选项是使用Spring Cloud Bus,它或多或少是我列表中的第二个选项。节点之间的信息传输正在通过AMPQ协议完成,但是他们在路线图上有其他传输方式如JMS。现在我们使用AMPQ。

1、使用RabbitMQ和Spring Cloud Bus

需要做的就是:

  • 将spring-cloud-starter-bus-amqp依赖项添加到classpath
  • 确保消息中间件正在运行。
  • 如果你在localhost(测试)上运行它,你不需要做任何事情.。如果您单独运行RabbitMQ,则需要在每个节点上配置以下内容:
代码语言:javascript复制
spring:
  rabbitmq:
    host: <broker host>
    port: <broker port>
    username: <broker user>
    password: <broker password>

2、配置Spring Cloud Config Server

Spring Cloud Bus提供的是将指令或配置发送到侦听总线的MicroServices,以通过以下内置HTTP端点触发的AMPQ消息重新加载Spring应用程序属性(它的行为类似于分布式actuator):

代码语言:javascript复制
"to invoke the reload of all application.properties of all MicroServices listening on the BUS"

/bus/refresh

"to invoke the reload of application.properties config of specific MicroService"

/bus/refresh?destination=<spring.application.name>:<app port>

"to send a specific key/value pair to MicroService Spring environment"

/bus/env

Spring Cloud Config通常是一个具有存储在GIT仓库中的属性的组件。它们支持许多公共git门户网站,如GitHub,Bitbucket,GitLab ...如果您想使用其他存储如数据库来存储属性,也可以使用Oracle等配置。

现在使用GIT。我们将以下属性保存到此GIT仓库中:

代码语言:javascript复制
service.dataBatchSize = 1

在microservice-spring-cloud-bus / config文件夹下,配置pring Cloud Config服务器的地址:

代码语言:javascript复制
spring.cloud.config.server.git.uri=https://tomask79@bitbucket.org/tomask79/microservice-spring-cloud-bus.git
spring.cloud.config.server.git.searchPaths=microservice-spring-cloud-bus, config

这个配置在告诉服务器根据spring.cloud.config.server.git.uri属性值获取配置存储库,并尝试搜索几个文件夹以找到配置文件。

我们将使用名为citiesService,personsService的两个MicroServices 来监听RabbitMQ总线。因此config子文件夹将包含citiesService.properties和personsService.properties文件。

文件名对应到客户端的spring.application.name属性值。

2、客户端使用Spring Cloud Config Server

每个MicroService都需要具有以下bootstrap.properties:

代码语言:javascript复制
spring.cloud.config.uri=http://localhost:9999
spring.cloud.config.enabled=true

这样,这个微服务就可以到配置服务器找到我之前配置的属性service.dataBatchSize。让我们在以下简单的citiesService使用这个属性。

代码语言:javascript复制
@RestController
@RefreshScope
public class CitiesController {

    @Value("${service.dataBatchSize:0}")
    private int dataBatchSize;

    final City[] cities = {
            new City("Brno", "Czech republic"),
            new City("Bern", "Switzerland"),
            new City("Berlin", "Germany"),
            new City("London", "England")
    };

    @RequestMapping("/cities")
    public Cities getCities() {
        final Cities result = new Cities();

        for (int i=0; i < dataBatchSize; i  ) {
            result.getCities().add(cities[i]);
        }

        return result;
    }
}

测试:

代码语言:javascript复制
首先启动RabbitMQ消息系统(启动取决于您安装它的环境)
git clone https://bitbucket.org/tomask79/microservice-spring-cloud-bus.git
mvn clean install(在pom.xml的根文件夹中)
cd spring-microservice-registry
java -jar target / registry-0.0.1-SNAPSHOT.war
验证NetFlix Eureka是否在http:// localhost:9761上运行
cd ..
cd spring-microservice-config
java -jar target / config-0.0.1-SNAPSHOT.war
cd ..
cd spring-microservice-service1
java -jar target / service1-0.0.1-SNAPSHOT.war
在http:// localhost:9761验证citiesService已注册
cd ..
cd spring-microservice-service2
java -jar target / service2-0.0.1-SNAPSHOT.war
在http:// localhost:9761验证personsService已经注册

一切正常后可访问:http://localhost:8081/cities

您应该看到大小等于“service.dataBatchSize”属性的城市列表。现在更改GIT仓库中citiesService.properties文件中的属性。如果您再次点击http:// localhost:8081 / cities,那么您将看不到任何更改...要重新加载citiesService MicroService的Spring上下文,请运行以下命令:

代码语言:javascript复制
(you can run this at any node having spring-cloud-starter-bus-amqp dependency)
curl -X POST http://localhost:9999/bus/refresh

也可以使用Postman的REST客户端提交刷新。

2. Spring Cloud Zuul作为微服务网关

在编写微服务时,您将面临以下问题:

  • 来自客户端的一个请求跨多个微服务调用
  • 你需要如何做金丝雀版本发布机制
  • 您需要反向代理来调用微服务

类似Nginx一个总的入口网关。

1、Spring Cloud Zuul作为反向代理

在将微服务部署到Docker时,需要处理多个微服务映射到多个端口的问题。但是,您的API消费者不希望知道这些端口,他们只需要在8080端口调用其他所有端口的所有内容。这里有很多解决方案,但使用Spring Cloud Zuul真的很棒!

让我们在端口8081和8082上运行两个微服务citiesService和personsService的先前演示,并为此做出反向代理,以便可以在一个端口下调用这两个服务:

代码语言:javascript复制
http://localhost:8080/cities  -> (redirect) -> http://localhost:8081/cities
http://localhost:8080/persons -> (redirect) -> http://localhost:8082/cities

在 Spring Cloud Zuul 下配置:

代码语言:javascript复制
spring.application.name=personsService
eureka.client.serviceUrl.defaultZone=http://localhost:9761/eureka
eureka.client.healthcheck.enabled=true

zuul.routes.persons.path=/persons
zuul.routes.persons.serviceId=personsService

zuul.routes.cities.path=/cities
zuul.routes.cities.serviceId=citiesService

ribbon.eureka.enabled=true
server.port=8080

我们在这里有两条路由: /persons 和/cities。每次对路由'/ persons'的调用都将被重定向到在Netflix Eureka服务器上注册的personsService 。每次调用“/ cities”网址都会被重定向到在Eureka注册的cititesService。

测试:

代码语言:javascript复制
* Start RabbitMQ broker first (start depends on the environment you've got it installed in)
* git clone https://bitbucket.org/tomask79/microservice-spring-cloud-zuul.git
* mvn clean install (in the root folder with pom.xml)

* cd spring-microservice-registry
* java -jar target/registry-0.0.1-SNAPSHOT.war
verify that NetFlix Eureka is running at http://localhost:9761

* cd ..
* cd spring-microservice-config
* java -jar target/config-0.0.1-SNAPSHOT.war

* cd ..
* cd spring-microservice-service1
* java -jar target/service1-0.0.1-SNAPSHOT.war
verify at http://localhost:9761 that citiesService has been registered

* cd ..
* cd spring-microservice-service2
* java -jar target/service2-0.0.1-SNAPSHOT.war
verify at http://localhost:9761 that personsService has been registered

* cd ..
* cd spring-microservice-zuul
* java -jar target/spring-cloud-zuul-0.0.1-SNAPSHOT.war
(this will start your reverse proxy)

在浏览器运行:

代码语言:javascript复制
http://localhost:8080/persons
http://localhost:8080/cities

0 人点赞