本系列内容作为本人在学习SpringCloud的一些记录,也希望提供给同样在学习cloud并且疯狂踩坑的老哥们一些参考,共勉之。至于概念性的东西我就不多赘述了,相信网上很多大神已经做出了相对成熟的解释。
首先我们为什么需要注册微服务呢?试想一下,如果我们又A服务和B服务两个服务,我们在A服务中要调用B服务的接口,因为我们是知道B服务的地址和信息,我只需要配置一下就行了。那如果因为业务不断扩张,我觉得B服务一个服务器不够用,我要加三五个进去,再过段时间热度下来了,我又要关闭几台B服务,总之它是一个动态的东西。这个时候就需要不断地去修改配置,重启服务等等一系列的操作。注册服务之后呢?我仅仅需要向注册中心发送请求,由注册中心主动去发现中需要调用的服务。这也太棒了叭。
- 注册中心
- 服务注册
- 高可用注册中心
1、主工程
首先建立一个主maven工程,spring Boot的版本是2.0.3.RELEASE,Spring Cloud版本采用Finchley.RELEASE ,我用下面的pom.xml限定了一些依赖的版本,如下所示
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zengg</groupId>
<artifactId>zeng-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zeng-cloud</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Cairo-SR2</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、注册中心
我开始建立一个服务的发现者,也就是eureka server 注册中心。在这个当前主工程项目下建立一个modular工程,如下所示
<groupId>com.zengg</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.zengg</groupId>
<artifactId>zeng-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
到这个时候我们可以直接启动这个boot项目看看有什么信息
上面的这个错误告诉我们我们只用了Eureka Server的依赖,但是没有办法注册服务。这个时候再启动类上加一个@EnableEurekaServer就行了,如下。
SpringBoot.png
这个时候再次启动项目,依然会报无法注册的错误,而且是每间隔一会就会报一次错误,为什么发生这样的事情呢?
实际上@EnableEurekaServer虽然声明了当前项目是一个服务的发现者,但是实际上它本身也是一个服务,在没有声明的情况下默认也是需要注册的。Eureka通过心跳的方式去确认服务是否还是正常状态,每隔一段时间,就会发送一次心跳,服务没有注册进去当然会隔一会就报错了。
此时再修改一下配置文件,加入
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/
server:
port: 1001
为什么这么配置呢?点击这个配置看看代码怎么说,可以看到Eureka在加载的时候默认给了一个8761的端口作为服务发现者。我们可以根据需求自由地去修改这个ip和端口。
再次重启项目,打开浏览器进入http://localhost:1001/
页面如下
可以看到已经有一个UNKNOWN的服务被注册进来了,实际上它就是Server本身,我们只有一个Eureka的时候,它本身是需要被注册进来的,我们修改两个地方
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/
register-with-eureka: false #表示本身不被注册进来
spring:
application:
name: eureka #本身的服务名 ,上面那个register-with-eureka: false还没有的时候试一下,UNKNOWN会变化
server:
port: 1001
到这里我们就完成了Eureka注册中心的内容了。
3、服务注册
接下来开始弄一个服务并注册进来,同样在主工程下建立一个modular,名为service-provide,pom文件如下
<groupId>com.zengg</groupId>
<artifactId>service-provide</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-provide</name>
<parent>
<groupId>com.zengg</groupId>
<artifactId>zeng-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 注册服务依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
同样的,既然是服务,我们也需要在启动类加入注解@EnableEurekaClient或者@EnableDiscoveryClient(前者用在Eureka作为注册中心的情境下,后者emmm,应该在Eureka或者其他注册中心下都能用)
配置文件如下,将服务注册到注册中心
spring:
application:
name: service-provide
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/
server:
port: 2002
然后启动项目,再次进入http://localhost:1001/ ,发现服务以及注册成功了
4、高可用
我们之前仅有一个注册中心,如果这个EurekaServer突然原地爆炸了,那岂不是注册到其上的所有服务都不能用了呢,这当然是我们不愿意看到的。
既然EurekaServer也可以算作是一个服务,那么我们可以直接建立两个注册中心,让它们相互注册,这样就完成了两个注册中心同时可用了
# 第一个注册中心的配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:1002/eureka/
server:
port: 1001
spring:
application:
name: eureka
# 第二个注册中心的配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/
server:
port: 1002
spring:
application:
name: eureka
先启动EurekaServerApplication1 ,这个时候回报无法注册的错误,这是因为我们还没有启动第二个注册中心,接下来我们启动EurekaServerApplication2 。在心跳机制下,过一会儿,发现第一个注册中心不会报错了。这个时候我们两个注册中心都启动成功了。
接下来回到service-privode服务,启动这个项目。分别进入http://localhost:1001和http://localhost:1002,就会发现这个服务在两个注册中心都注册成功了。不过这还没完!
我们可以看到,service-privode仅仅注册进了1001注册中心,虽然启动后1002也能发现该服务。
如果当1001注册中心先行挂掉,然后service-privode也挂掉了。我们先不重启1001注册中心,直接重启service-privode,就会发现该服务并没有直接注册到1002注册中心里。这个时候我们需要对原有配置进行修改。我们可以把service-privode直接注册到两个注册中心里面
spring:
application:
name: service-provide
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/,http://localhost:1002/eureka/
server:
port: 2002
如上所示
最后提一下三个Eureka注册中心的场景,它的模式和两个注册中心类似,我用1001、1002、1003端口分别作为三个注册中心的端口,每一个注册中心都需要注册到另外两个注册中心里
# 第一个注册中心的配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:1002/eureka/,http://localhost:1003/eureka/
server:
port: 1001
spring:
application:
name: eureka
# 第二个注册中心的配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/,http://localhost:1003/eureka/
server:
port: 1002
spring:
application:
name: eureka
# 第三个注册中心的配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:1001/eureka/,http://localhost:1002/eureka/
server:
port: 1003
spring:
application:
name: eureka
打完收工!
网友评论