eureka是一个服务发现注册框架,它保证了AP原则,即保证了可用性+分区容错性。
CAP原则指的是在分布式系统中,最多只能满足其中两个需求,不可能三个需求全部满足。
那么什么是CAP?
C(一致性):Consistency
A(可用性):Availability
P(分区容错性):Partition tolerance
CA:满足一致性+可用性,之前的单体应用,基本上都是CA原则。而现在流行的分布式,P是不可或缺的。
AP:满足可用性+分区容错性,即系统是高可用的但是是弱一致性。如果系统对数据的一致性要求不高于系统的可用性,就应该使用AP原则。
CP:满足一致性+分区容错性, 即系统是高一致性但是是弱可用的。如果系统对数据的一致性要求要高于系统的可用性,那么就应该使用CP原则。
好了,回归正题…… 开始实战。
一、创建项目,导入pom依赖
遇到的问题:
springcloud与springboot版本不匹配
springcloud和springboot之间的版本要求严格,不符合相关的版本启动就会报错。采集版本关系,见如下表格。
springcloud | springboot |
---|---|
Hoxton.SR12 | >=2.2.0.RELEASE and <2.4.0.M1 |
2020.0.5 | >=2.4.0.M1 and <2.6.0-M1 |
2021.0.0-M1 | >=2.6.0-M1 and <2.6.0-M3 |
2021.0.0-M3 | >=2.6.0-M3 and <2.6.0-RC1 |
2021.0.0-RC1 | >=2.6.0-RC1 and <2.6.1 |
2021.0.0 | >=2.6.1 and <2.6.4-SNAPSHOT |
2021.0.1-SNAPSHOT | >=2.6.4-SNAPSHOT and < 3.0.0-M1 |
2022.0.0-M1 | >=3.0.0-M1 and < 3.1.0-M1 |
详情点击访问:
https://start.spring.io/actuator/info
引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-->改版本号要与springboot版本匹配<-->
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
客户端、服务端都引入相同依赖
二、创建eureka服务端
让一个项目作为eureka的服务端,只需要在XxxApplication.java上加上@EnableEurekaServer
注解即可。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置application.properties,让客户端的服务能够找到指定的服务端,并进行注册。
spring.application.name=eureka
##当前服务为注册服务,不将自己注册到服务中心
eureka.client.register-with-eureka=false
## 不拉取服务注册信息
eureka.client.fetch-registry=false
## 客户端注册服务端链接
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
##是否开启自我保护,默认是true
eureka.server.enable-self-preservation=false
##自动清理客户端实例的间隔
eureka.server.eviction-interval-timer-in-ms=3000
server.port = 8000
然后直接启动Application即可,然后访问服务端:http://localhost:8000/
三、创建Eureka客户端
同样的让一个项目变成Eureka客户端,也只需要在XxxApplication.java上加注解@EnableDiscoveryClient
或者@EnableEurekaClient
其中之一即可,但是如果加上的是@EnableEurekaClient注解,那么该客户端只支持向Eureka服务端注册,而@EnableDiscoveryClient注解则支持向所有的服务注册框架进行注册。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class DriverApplication {
public static void main(String[] args) {
SpringApplication.run(DriverApplication.class, args);
}
/**
* 给RestTemplate加上LoadBalanced
* 即让RestTemplate在请求时拥有客户端负载均衡的能力
*/
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
还是需要配置一下application.properties文件,如下:
##注册到服务端实例的名字
spring.application.name=onlinecar-driver
eureka.client.enabled=true
eureka.client.service-url.defaultZone = http://localhost:8000/eureka/
server.port = 8001
启动后,在服务端页面可以看到已经注册了一个实例
如果启动后发现页面飘了一段红字:
这是因为我们对服务端开了自我保护机制,有两种解决方案:
1、将自我保护自己关闭
2、调整服务续约配置
##在服务端application中配置
##心跳间隔秒数,即如果90秒内还没有接收到客户端的心跳的话,就会将该客户端的实例删除
eureka.instance.lease-expiration-duration-in-seconds=90
##客户端续约秒数,即30秒内客户端要与服务端进行续约,默认可以延迟3个周期
eureka.instance.lease-renewal-interval-in-seconds=30
##自我保护系数
eureka.server.renewal-percent-threshold=0.85
为了测试服务调用,我们就再建一个客户端2,server.port与spring.application.name需要变变,让客户端1调用客户端2的接口。
哒哒哒哒哒哒…… 启动好了
四、调用接口
客户端1代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/order")
public class DriverController {
@Autowired
RestTemplate restTemplate;
@RequestMapping("/do/{driverId}")
public String order(@PathVariable String driverId){
return driverId;
}
}
客户端2代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/dispatch")
public class DispatchController {
@Autowired
RestTemplate restTemplate;
@RequestMapping("/do/{userId}")
public String doDriver(@PathVariable String userId){
String url = "http://onlinecar-driver/order/do/"+userId;
return restTemplate.getForObject(url,String.class);
}
}
其中onlinecar-driver就是服务端的实例名,那么我们调用客户端的doDriver方法。
没有问题。
以上就是对eureka的一点简单的实战。