Spring Cloud –基本设置

Spring Cloud解决了分布式系统的常见问题。 但是,对于只使用广为人知的整体应用程序工作的人来说,从一开始就跳入一长串为分布式服务设计的模式可能会让人不知所措。 本文将通过实用的方法为您介绍Spring Cloud的基础知识。 完成后,您不仅应该知道如何基于Spring Cloud启动项目,还应该了解为什么需要所有步骤以及它们解决了哪些问题。

1.第一服务

让我们定义一下我们将使用Spring Cloud解决的问题。 该演示的目的是为分布式博客平台奠定基础。

分布式系统的核心组件是服务,它不过是旨在专注于域的特定部分的常规应用程序。 在一个复杂的系统中,可能会有数十种不同的服务,但是为了清楚起见,我们仅从两个示例开始。 第一项服务将照顾作者,而第二项服务将专注于文章。

作者服务

在我们的例子中,作者服务是使用spring-boot-starter-web创建的典型Spring Boot应用程序。 目前,我们不使用Spring Cloud的任何功能。

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

这是一个作者域类,这是我们第一个服务的主要重点。

class Author {private final Long id;private final String name;//…}

最后,我们创建一个REST控制器,该控制器允许提取所有作者或根据其标识符查找特定作者。

@RestController
class AuthorController {//…@GetMappingList<Author> findAll() {//…}@GetMapping("/{id}")Author findOne(@PathVariable long id) {//…}}

文章服务

第二项服务类似于上一项。 如果需要代码示例,可以在GitHub存储库中找到它们 。

此步骤的关键是要认识到,我们将域的不同部分分为较小的和松散耦合的应用程序,而不是一个较大的应用程序。 它给我们带来什么? 有许多优点,例如,更简单的可伸缩性,弹性或更快的部署。 如果您需要更多的理论背景,建议您阅读Sam Newman撰写的一本很棒的书,名为Building microservices 。

2.分布式配置

如果您尝试在一台机器上启动这两种服务,则默认的Spring Boot设置将无法实现,因为这两个应用程序都将尝试在端口8080上运行。您可以自定义设置并在每个应用程序的application.properties中选择不同的端口。应用程序,这对于两个服务来说不是问题,但对于许多服务而言,可能会更成问题。

配置服务器

对于复杂的分布式系统,明智的做法是将所有服务的配置都放在一个位置,以简化整个管理过程。 为了适合微服务系统,这些配置将由…另一服务提供。 创建应用程序,并将以下依赖项放入pom.xml中

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId>
</dependency>

配置服务器中的主要应用程序类与其他应用程序没有太大区别。 唯一的区别是之前添加的Spring Cloud依赖项中的@EnableConfigServer批注,该批注负责为外部配置公开API。

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

配置位置

我们将在哪里保留服务的配置? 配置服务器JAR文件中的捆绑属性不是一个灵活的解决方案。 一些外部位置似乎是一个更好的主意。 默认情况下,Spring Cloud使用Git存储库来管理配置。 可以在配置应用程序的application.properties中设置Git服务器的URI地址(以及其他详细信息)。 幸运的是,在我们的演示中,我们不需要单独的Git服务器。 出于测试目的,本地存储库可以正常工作。

server.port=9001
spring.application.name=config-serverspring.cloud.config.server.git.uri=file://${user.home}/config

Git存储库的位置是通过spring.cloud.config.server.git.uri属性设置的。 为了使用真实服务器,应将值更改为不带file:前缀的某些URL。 我们还更改了默认端口,以避免在单台计算机上运行时与其他服务冲突。 此外,该应用程序收到了自己的名称。 目前不需要,但稍后我们将使用该名称作为其他服务中对配置服务器的引用。

配置库

所有服务的配置都将保留在spring.cloud.config.server.git.uri中设置的位置。 现在,我们可以创建两个文件,专门用于以前开发的服务,在其中我们将更改默认端口并分配名称,就像对配置服务器所做的一样。

这是article-service.properties文件的内容。

server.port=9003
spring.application.name=article-service

此时的author-service.properties文件看起来几乎相同。

server.port=9004
spring.application.name=author-service

最后,初始化Git存储库并提交两个创建的配置。

git init
git add .
git commit -m 'Service configs'

3.服务发现

配置服务器已准备就绪,但其他服务仍不知道其存在以及如何获取其配置的方式。 该问题的一种可能解决方案是使用Spring Cloud Config Client将服务直接与服务器连接,该客户端可以添加spring-cloud-starter-config依赖项。 主要缺点是我们必须在每个服务中对配置服务器的地址进行硬编码。 如果此服务的位置将来发生更改,或者我们想提供冗余对等方,则所有服务都需要更新。 在称为“服务发现”的模式下解决了在分布式系统中查找其他服务的问题。

注册表服务器

我们已经为所有配置创建了服务器,这是我们的第一个基础架构服务。 同样,现在我们将开发一个注册表服务器,这是另一种基础结构服务,它将充当分布式系统中所有组件的地址簿。 创建具有以下依赖关系的新应用程序。

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency>
</dependencies>

第一个负责公开注册表API。 已经提到了第二个依赖关系,该依赖关系用于连接我们的配置服务器,该服务器还将保存我们正在创建的注册表的配置。 主应用程序类类似于其他Spring Boot应用程序。 我们仅添加@EnableEurekaServer批注以公开注册表API。

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

注册表服务器中最后缺少的是引导程序配置。 配置的主要部分将由配置服务器提供服务,但是我们需要描述如何找到它。 在main / resources目录中创建bootstrap.properties文件,并添加下面显示的行,这些行是配置服务器的地址和用于获取属性的注册表应用程序的名称。

spring.cloud.config.name=registry-server
spring.cloud.config.uri=http://localhost:9001

公开注册表配置

下一步是将配置添加到配置服务器监控的Git存储库中。 创建一个名为Registry-server.properties的文件。 重要的是,文件名必须与注册表服务器应用程序中bootstrap.properties文件中的spring.cloud.config.name属性值匹配。 最低要求的配置如下所示。 不要忘记将更改提交到Git存储库。

spring.application.name=registry-server
server.port=9002eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/

前两个属性是普通Spring Boot应用程序的典型属性。 其他三个专用于Spring Cloud Eureka Client。 默认情况下,每个Eureka服务器都将尝试连接到其他对等服务器以注册其存在。 在我们的简单演示中,我们只有一个注册表服务器实例,但是在生产解决方案中,您可能会提供此类服务的某些冗余。 我们的注册表服务器不会连接任何东西,这就是为什么我们将默认值更改为false的原因。 注册事件会传播到eureka.client.serviceUrl.defaultZone中列出的所有Eureka服务器,但是尽管只有一种,因为在我们这种情况下,我们仍然需要设置此属性以覆盖默认值。

使用外部配置运行注册表

目前,我们可以同时运行两个服务器,以验证它们是否按预期工作。 由于注册表服务器取决于配置服务器,因此需要首先启动它。 几秒钟后,也可以启动注册表服务器。 如果您没有遗漏任何步骤,则两个应用程序都应运行,日志中没有任何错误。 配置服务器应获取配置并在端口9002上运行。导航到http:// localhost:9002 /后 ,将显示Eureka仪表板,其中包含有关正在运行的实例的一些详细信息。

4.配置服务注册

我们的注册服务与配置服务器连接的事实并不意味着该服务器已注册为服务。 服务的责任是将其状态传达给分布式寄存器。 为了连接到注册表服务,配置服务器需要以下依赖关系。

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

它将允许我们在配置服务器的主类中使用Eureka客户端注释。

@EnableEurekaClient
public class ConfigServerApplication {//…
}

最后是注册表服务器的地址,必须将其添加到配置服务器的application.properties中。

eureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/

此时,您可能开始怀疑服务器之间的通信将如何进行。 注册表服务器需要从配置服务器进行配置,而同时配置服务器希望连接到注册表以通知其存在。 他们应该以什么顺序交流?

实际上,没有任何变化。 您首先启动配置服务器。 每隔几秒钟,它将尝试与注册表服务器连接并在每次失败时打印错误日志。 启动注册表服务器后,它将获取其配置并开始接受注册。 最后,配置服务器将注册,并且不再显示错误日志。 尝试一下以确认它是否按预期工作。

5.配置获取

我们的配置服务器最终可以通过本文开头创建的域服务发现。 首先,进行少量修改,我们需要针对作者和文章服务重复上一段的所有步骤,以允许与注册服务进行通信。 提醒一下,这些步骤是:

  • 添加对spring-cloud-starter-eureka的依赖
  • @EnableEurekaClient注释主类
  • bootstrap.properties中设置eureka.client.serviceUrl.defaultZone (不在application.properties中

这将允许服务与注册表服务器进行通信,但仍不会获取任何配置。 为了使这一过程自动化,我们需要在服务中提供另一个小的依赖项(请注意,注册表服务器中使用了相同的依赖项)。

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

最后,我们需要在bootstrap.properties中设置一些其他详细信息。 这是作者服务的示例文件。 类比属性应添加到Article服务。

spring.cloud.config.name=author-service
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.discovery.enabled=true

spring.cloud.config.name的值必须与配置服务器提供的配置库中的相应属性文件匹配。 第二个属性用于标识在我们的Eureka服务器中注册的配置服务器。 更改的值必须与配置服务器中application.properties中存在的spring.application.name值匹配。 使用最后一个属性,我们启用配置发现过程。

您应该能够验证两个服务是否都在集中式配置中定义的端口上启动。 如果您关闭了配置和发现服务,请先启动它们,然后再运行域服务。 只要所有步骤都正确完成,两个服务都应在配置的端口上响应浏览器。 在另一种情况下,确保您不会错过任何步骤或将代码与存储库中的示例进行比较 。

6.一劳永逸,一劳永逸

目前,我们实际上可以认为我们的基本设置已经准备就绪,但是我们将为难题添加另一部分,并了解分布式系统中使用的另一种模式,即服务网关。 顾名思义,其目的是允许客户端使用单个访问点查找所有服务。 换句话说,网关充当分布式服务的路由器。

网关服务

让我们在此演示中创建最后一个Spring Boot应用程序,并添加下面提到的依赖项。 唯一的新功能是spring-cloud-starter-zuul ,其中包含创建网关所需的类。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId>
</dependency>

除了以前添加的注释外,应用程序的主类还应使用@EnableZuulProxy声明自己为代理网关。

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayServiceApplication {public static void main(String[] args) {SpringApplication.run(GatewayServiceApplication.class, args);}}

该应用程序还需要bootstrap.properties文件,该文件的值类似于先前配置的域服务。 这里没有什么新东西需要解释。

spring.cloud.config.name=gateway-service
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.discovery.enabled=trueeureka.client.serviceUrl.defaultZone=http://localhost:9002/eureka/

配置获取

就像其他常规服务一样,网关依赖于配置服务器管理的Git存储库中存储的配置。 创建一个名为gateway-service.properties的文件,使用以下值设置其内容,然后将更改提交到配置库。

spring.application.name=gateway-service
server.port=8080zuul.routes.author-service.path=/authors/**zuul.routes.article-service.path=/articles/**

我们已经知道前两个值。 另外两个更有趣。 在这里,我们定义对于给定的URL模式,到网关的所有请求都应转发到由其名称标识的服务。 请注意,我们不会将网关与这些服务的任何特定主机地址耦合。 网关将使用先前创建的发现服务找到它们。

最终基本设置验证

启动网关之后,应用程序应在端口8080上进行侦听。尝试使用配置的映射访问这两个域服务:

http:// localhost:8080 / articles
http:// localhost:8080 / authors

网关模式使我们能够将API的客户端与运行服务的特定主机分离。 只有网关的地址必须与客户端共享。 网关还可以照顾重复服务的负载平衡,但是让我们将这个话题再留一遍。

7.总结

乍一看,基本的Spring Cloud设置似乎非常复杂,尤其是与典型的整体应用程序基础相比。 还有许多创建系统的构件。 但是,每个组件在设计时都考虑了“单一责任主体”。 我们了解了微服务体系结构中使用的三种基本模式,即服务发现,分布式配置和服务网关。 他们每个人都有一个专用的应用程序,仅专注于单个任务。 划分职责是微服务体系结构的主要要素,即使我们创建的小型演示在实践中也极大地描述了这个想法。

翻译自: https://www.javacodegeeks.com/2017/10/spring-cloud-basic-setup.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eclipse中的Tomcat:6个流行的“如何做”问题

学习新技术总是一个艰难的过程。 当您尝试学习将要相互交互的两种技术时&#xff0c;此过程变得更加困难。 Tomcat和Eclipse是Java EE开发中最流行的先决条件之一。 因此&#xff0c;要成为一名专业的开发人员&#xff0c;您需要知道如何使用此对执行最需要的操作以及如何进行一…

Spring Boot中带有CKEditor的AJAX

1.概述 在本文中&#xff0c;我们将介绍如何在Spring Boot中使用CKEditor 。 在本教程中&#xff0c;我们将导入一个包含大量数据的XML文档&#xff0c;对使用GET请求将一组数据加载到CKEditor实例的能力进行编程&#xff0c;并执行POST请求以保存CKEditor的数据。 我们将使用…

使用Http协议访问网络--HttpClient

public interface HttpClient org.apache.http.client.HttpClient HttpClient是Apache提供的Http网络访问接口。1、创建HttpClient实例HttpClient是一个接口&#xff0c;无法直接创建实例&#xff0c;通常创建一个DefaultHttpClient&#xff08;HttpClient 的SubClass&#xff…

编写测试用例

1、创建测试用例 为ComeOnBroadcastReceiverDo创建一个测试用例&#xff1a; 在导航栏File-->New-->Other 选择AndroidTestProject 2、点击next输入测试工程的name&#xff0c;选择测试工程路径 点击next,选择要测试的工程&#xff1a; 点击Finish完成测试工程的新建 被…

欢迎界面动画

实现一个欢迎界面的动画&#xff0c;即打开app显示的页面&#xff0c;动画结束后跳到Activity。 1、欢迎界面的背景是一个绿色矩形 <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/andr…

IP地址分类及ISO-OSI、三次握手

1. A类地址A类地址的表示范围为&#xff1a;0.0.0.0~126.255.255.255(00000000~01111110)&#xff0c;最前面一位是“0”&#xff0c;用7位&#xff08;bit&#xff09;来标识网络号&#xff0c;24位标识主机号&#xff1b;默认网络掩码为&#xff1a;255.0.0.0&#xff0c;111…

drools 决策表_骆驼和春天的Drools决策表

drools 决策表正如我在之前的文章中所展示的那样&#xff0c; JBoss Drools是一个非常有用的规则引擎 。 唯一的问题是&#xff0c;对于非技术人员而言&#xff0c;以Rule语言创建规则可能会非常复杂。 这就是为什么人们可以提供一种简便的方法来创建业务规则-在电子表格中创建…

在Java中处理异常

每个程序员都希望编写一个完美的程序。 也就是说&#xff0c;程序运行时没有任何障碍。 好吧&#xff0c;如果希望是马&#xff0c;乞g就会骑。 除了程序员的所有愿望之外&#xff0c;有时还会发生无法预料的情况。 这些不可预见的情况在Java中通常被归类为“例外”。 异常会…

通信系统的组成

数字通信模型&#xff1a; http://blog.csdn.net/yaosiming2011/article/details/44280797 进程和线程

存储卡显示0字节怎么办?恢复0字节的存储小技巧

存储卡显示0字节是一个常见的故障现象&#xff0c;可能由多种原因引起。本文将详细分析存储卡出现此类问题的各种原因&#xff0c;并提供针对性的解决方法。通过深入了解这些原因和解决方案&#xff0c;读者可以有效地应对存储卡显示0字节的故障&#xff0c;从而恢复存储卡的正…

OSI模型和TCP/IP协议族

1、协议分层 两个实体之间要进行通信就需要有一个协议。而当通信比较复杂时就有必要将这个复杂的任务划分为多层&#xff0c;就需要有多个协议&#xff0c;每一层都有自己的协议。 2、ISO 国际标准化组织&#xff08;International Standard Organization &#xff0c; ISO&…

在PhotoShop中改像素m*n

快捷键&#xff1a;CtrlAlti&#xff0c;如图&#xff0c;改为28*28

Spring Boot Redis简介

1.概述 在本文中&#xff0c;我们将通过Spring Data Redis库回顾如何将Redis与Spring Boot结合使用的基础知识。 我们将构建一个应用程序&#xff0c;演示如何通过Web界面执行CRUD操作Redis 。 Github上提供了该项目的完整源代码。 2.什么是Redis&#xff1f; Redis是一个开源…

Dijkstra-解决最短路径问题

1、从A开始&#xff08;也可以从其他点&#xff0c;此处选择从A&#xff09; 将A 加入树&#xff0c;A被圈红 列出最短路径数组&#xff1a; 2、 确定从A到其他顶点的最短距离为50&#xff0c;A-->B 将B加入树&#xff1a; 更新最短路径数组&#xff1a; 比较到C的距离&a…

简单排序--冒泡排序

冒泡排序&#xff1a; public void sort(){int out,in;//out指向已经排好序的前一个for( outnElements-1;out>1;out--){for(in0;in<out;in){if(arr[in]>arr[in1]){swap(in,in1);//相邻的两个元素比较&#xff0c;交换}}}}//实现冒泡排序相邻的元素两两比较&#xff0c…

简单排序--选择排序

选择排序&#xff1a; public void sort(){int out,in,min;for(out0;out<nElements-1;out){min out;for(inout1;in<nElements;in)if(arr[in]<arr[min])min in;swap(out,min);//将min放在out位置&#xff0c;out始终指向最小值的下一个位置&#xff0c;即下一个min要…

Java 9模块服务

接线与查找 Java长期以来都有一个ServiceLoader类。 它是在1.6中引入的&#xff0c;但是自Java 1.2以来就使用了类似的技术。 一些软件组件使用了它&#xff0c;但是使用并不广泛。 它可以用于模块化应用程序&#xff08;甚至更多&#xff09;&#xff0c;并提供一种使用应用程…

简单排序--插入排序

插入排序&#xff1a; public void sort(){int in,out,temp;for(out1;out<nElements;out){temp arr[out];in out;while(in>0&&arr[in-1]>temp){arr[in] arr[in-1];//待插入的数据比其之前的数字大的右移&#xff0c;从小到大排序--in;//依次左移}arr[in] …