一、关于版本的选择
在使用springcloud的时候,经常会因为一些版本的问题导致搭建项目受阻。其实spring提供了一个简单的springcloud和springboot版本选择的接口,直接访问该接口可以很明确的看到相互依赖的版本
https://start.spring.io/actuator/info
访问该接口,出现以下内容:
这样就可以很容易的看到到底springboot和哪个版本的springcloud搭配使用才是合理的。
二、eureka服务治理中心
1、POM文件
首先我们再父工程定义好springboot和springcloud的版本,方便我们在子项目中管理jar包的导入,最后我们使用三个工程来演示eureka的服务治理和发现,结构如下
<?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.lwb</groupId>
<artifactId>lwb-project</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<parent>
<!--版本判断 https://start.spring.io/actuator/info-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<properties>
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
<java.version>8</java.version>
</properties>
<modules>
<!--这是父工程下的三个子项目-->
<module>lwb-spring-eureka-server</module>
<module>lwb-spring-eureka-client-order</module>
<module>lwb-spring-eureka-client-goods</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
这里选择的springboot版本是2.3.2.RELEASE,springcloud的版本是Hoxton.SR12,这也是从第一章的接口信息中判断的。
下面开始创建eureka服务端项目lwb-spring-eureka-server
,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">
<parent>
<artifactId>lwb-project</artifactId>
<groupId>com.lwb</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lwb-spring-eureka-server</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--启动spring的基础组件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
解释各个包的作用:
spring-boot-starter-web
:springboot的web工程必要依赖,没有个包无法正常使用
spring-boot-starter-actuator
:springboot提供的监控相关的包,后面会使用到
spring-cloud-starter-netflix-eureka-server
:eureka服务端核心包,做eureka服务端,这个包就够了
2、配置文件application.yml
# 启动端口
server:
port: 8080
# 服务名称,非常重要
spring:
application:
name: spring-eureka
eureka:
client:
# 是否把当前服务注册到eureka中,因为该项目就是eureka注册中心,因此没有必要自己注册自己,设置为false,表示不注册
register-with-eureka: false
# 表示是否从注册中心同步注册的服务,由于该项目是注册中心,没有必要拉取服务列表,因此设置为false
fetch-registry: false
# 服务注册域地址,以后的服务要注册到注册中心中,就是配置这个地址
service-url:
defaultZone: http://127.0.0.1:8080/eureka
# 是否开启自我保护,一般来说测试环境没有必要开启,正式环境建议开启
server:
enable-self-preservation: true
3、主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author 隐市高手
* @date 2022/5/21 15:09
*/
@SpringBootApplication
@EnableEurekaServer
public class AppEurekaServer {
public static void main(String[] args) {
SpringApplication.run(AppEurekaServer.class, args);
}
}
主启动类和一般的一般的springboot主启动类没有多大区别,唯一多了个注解@EnableEurekaServer
,表示开启注册中心。
4、启动结果
启动主启动类,访问http://localhost:8080
,得到eureka的管理页面:
需要注意的是,我们再启动的时候,有这样一个日志:
我经常犯的一个错误就是认为这个打印的地址就是访问eureka主页的地址,然后用这个地址去浏览器访问,总是得到404,然后各种百度找问题😪😪😪😪😪
三、eureka服务发现
1、pom文件
创建子项目lwb-spring-eureka-client-goods
,其pom文件如下:
<?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">
<parent>
<artifactId>lwb-project</artifactId>
<groupId>com.lwb</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lwb-spring-eureka-client-goods</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
其实和治理中心导入的依赖基本相同,只不过一个是server(治理中心),另一个是client客户端
2、配置文件application.yml
spring:
application:
name: spring-goods
server:
port: 8082
eureka:
client:
service-url:
# 注册中心地址
defaultZone: http://127.0.0.1:8080/eureka
# 注册到治理中心后,显示ip和端口
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
3、主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author 隐市高手
* @date 2022/5/21 16:07
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class AppEurekaClientGoods {
public static void main(String[] args) {
SpringApplication.run(AppEurekaClientGoods.class, args);
}
}
@EnableEurekaClient
:开启eureka客户端功能
EnableDiscoveryClient
:自动发现服务功能
其实这两个注解只是在老版本中需要,在我们这个版本中,不要这两个注解功能依然可以正常
4、启动结果
5、多个服务注册
上面我们已经注册了一个服务到注册中心了,从工程结构来,再注入另一个服务,当前服务一样,只需要把配置文件中的端口和application.name改一下即可,然后启动注入到注册中心里。
四、关于集群
治理中心集群,只需要改下端口号,多启动几个,然后在defaultZone的配置这里用逗号隔开,多写几个地址而已。
而客户端也是一样,多改几个端口,多启动几个进程,修改下注册中心地址,使用逗号隔开。
非常简单,如果遇到问题,可自行百度
五、服务治理中心工作原理
1、微服务实例和服务治理中心的关系
先上图,在集群的架构中,一个简易的原理图如下:
①注册
在将具体的微服务实例注册到Eureka服务端时,是通过REST风格请求其配置的属性eureka.client.serviceUrl.defaultZone生成的URL来完成的,这时,微服务会将其自身的信息传递给Eureka服务端
,完成注册。配置项spring.application.name,是作为微服务名称来定义的,这样可以明确该实例归属于哪个微服务。
注意,当启动微服务时,它并不会马上向Eureka服务治理中心发送REST请求,在Eureka服务治理中心注册,它会延迟40秒才发起请求,所以在启动微服务的时候,需要稍等一会儿才能在Eureka服务治理中心页面中看到注册信息。
②续约
在我们将具体的微服务实例注册到Eureka服务端后,并不能保证该实例一直可用,因为该实例可能出现网络故障、机器故障或者服务宕机等,所以具体的微服务实例会按照一个频率对Eureka服务器维持心跳,告诉Eureka该实例是可用的,借此来避免被Eureka服务端剔除出去,这样的行为被称为续约。
③下线
在系统出现故障,需要停止或者重启某个微服务实例的时候,在正常操作下,实例会对Eureka发送下线REST风格请求,告知服务治理中心,这样客户端就不能再请求这个实例了。
2、服务治理中心
①相互复制
Eureka本身也会相互注册,以保证高可用和高性能。各个Eureka服务器之间也会相互复制,也就是当微服务发生注册、下线和续约这些操作的时候,Eureka会将这些消息转发到其他服务治理中心的实例上,这样就完成同步了。需要注意的是,这里的Eureka服务器之间采用的是对等模式(Peer-to-Peer),也就是每一个Eureka都是等价的,这有别于分布式中的主从模式(Master-Slave)。
②服务剔除
在实际的工作中,有时候有些服务会因为网络故障、内存溢出或者宕机而导致服务不能正常工作,这个时候就要将这些无效的服务实例剔除出去。Eureka Server在启动时,会创建一个定时任务,在默认的情况下,每间隔60秒就会更新一次微服务实例的清单,只要发现有超过90秒没有完成续约的实例,就会将其剔除出去。
③自我保护
Eureka的自我保护机制。在我们启动实例的时候,微服务实例都会自动查找Eureka进行注册,Eureka实例也是如此。在Eureka注册之后,它自己也会通过心跳来告诉自己还活着。在Eureka运行期间,如果在15分钟内低于85%的情况下心跳测试失败,它就会出现警告(在单机测试中很容易出现,在实际生产环境中往往是网络故障)。
3、微服务之间的相互调用
①服务获取
服务获取是指微服务实例作为Eureka的客户端,从Eureka服务治理中心获取其他微服务实例清单的功能。它还会将该服务实例清单缓存到本地,并且按一定的时间间隔刷新。
当我们启动微服务实例的时候,它就会以一个时间间隔(默认是30秒)向Eureka服务治理中心发送REST风格请求,获取一份只读的服务实例清单,跟着进行缓存,在下一个时间间隔再发送REST风格请求到Eureka,获取最新的服务实例清单,以确定哪些实例可用,哪些实例不可用。
②服务调用
服务调用是指一个微服务调用另一个微服务的过程。在SpringCloud中,大部分会采用REST风格请求。一个微服务下存在多个实例,那么会采用哪个实例呢?
首先,我们之前谈过服务获取的功能,它会从Eureka服务治理中心拉取一份服务实例清单,然后通过某种负载均衡的算法,选择具体的实例,所以这里服务调用的过程核心往往就是负载均衡的算法了