SpringCloud学习心得——Eureka注册中心
定义
Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 REST 的服务,并且提供了基于 Java 的客户端组件,主要负责实现微服务架构中的服务治理功能。
与Zookeeper区别与联系
CAP 定理:即 C 为数据一致性;A 为服务可用性;P 为服务对网络分区故障的容错性。这三个特性在任何分布式系统中都不能同时满足,最多同时满足两个。
Eureka 是基于 AP 原则构建的,而 ZooKeeper 是基于 CP 原则构建的。
- Zookeeper 有一个 Leader,而且在这个 Leader 无法使用的时候通过 Paxos(ZAB)算法选举出一个新的 Leader。这个 Leader 的任务就是保证写数据的时候只向这个 Leader 写入,Leader 会同步信息到其他节点。通过这个操作就可以保证数据的一致性。
- 去 Eureka 中去拉取服务列表,查看你调用的服务在不在其中,在的话就拿到服务地址、端口等信息,然后调用。
搭建Eureka中心
创建maven项目,添加如下依赖
知识兔div><!-- Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath /> </parent> <dependencies> <!-- eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <!-- Spring Cloud --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
261
知识兔div><!-- Spring Boot -->
2
知识兔div><parent>
3
知识兔div><groupId>org.springframework.boot</groupId>
4
知识兔div><artifactId>spring-boot-starter-parent</artifactId>
5
知识兔div><version>2.0.6.RELEASE</version>
6
知识兔div><relativePath />
7
知识兔div></parent>
8
知识兔div><dependencies>
9
知识兔div><!-- eureka -->
10
知识兔div><dependency>
11
知识兔div><groupId>org.springframework.cloud</groupId>
12
知识兔div><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
13
知识兔div></dependency>
14
知识兔div></dependencies>
15
知识兔div><!-- Spring Cloud -->
16
知识兔div><dependencyManagement>
17
知识兔div><dependencies>
18
知识兔div><dependency>
19
知识兔div><groupId>org.springframework.cloud</groupId>
20
知识兔div><artifactId>spring-cloud-dependencies</artifactId>
21
知识兔div><version>Finchley.SR2</version>
22
知识兔div><type>pom</type>
23
知识兔div><scope>import</scope>
24
知识兔div></dependency>
25
知识兔div></dependencies>
26
知识兔div></dependencyManagement>
添加启动类
知识兔div>@EnableEurekaServer @SpringBootApplication public static void main(String[] args) { SpringApplication.run(EurekaServer Application.class, args); } }
1
知识兔div>2
知识兔div>3
知识兔div>public static void main(String[] args) {
4
知识兔div>SpringApplication.run(EurekaServer Application.class, args);
5
知识兔div>}
6
知识兔div>}
添加配置文件
知识兔div>spring: application: name: myEureka-Server server: port: 8761 eureka: client: # 因为自己是主机,所以不向自己注册 register-with-eureka: false # 自己就是注册中心,所以不用去检索服务 fetch-registry: false
1
知识兔div>spring
2
知识兔div>application
3
知识兔div>name myEureka-Server
4
知识兔div>5
知识兔div>server
6
知识兔div>port8761
7
知识兔div>8
知识兔div>eureka
9
知识兔div>client
10
知识兔div># 因为自己是主机,所以不向自己注册
11
知识兔div>register-with-eurekafalse
12
知识兔div># 自己就是注册中心,所以不用去检索服务
13
知识兔div>fetch-registryfalse
运行,并访问,http://localhost:8761
创建服务提供者
创建项目注册到Eureka
- 新建maven项目,引入依赖
- 311
知识兔div><parent>
2
知识兔div><groupId>org.springframework.boot</groupId>
3
知识兔div><artifactId>spring-boot-starter-parent</artifactId>
4
知识兔div><version>2.0.6.RELEASE</version>
5
知识兔div></parent>
6
知识兔div><dependencies>
7
知识兔div>8
知识兔div><dependency>
9
知识兔div><groupId>org.springframework.boot</groupId>
10
知识兔div><artifactId>spring-boot-starter-web</artifactId>
11
知识兔div></dependency>
12
知识兔div>13
知识兔div><dependency>
14
知识兔div><groupId>org.springframework.cloud</groupId>
15
知识兔div><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
16
知识兔div></dependency>
17
知识兔div>18
知识兔div></dependencies>
19
知识兔div>20
知识兔div><!-- Spring Cloud -->
21
知识兔div><dependencyManagement>
22
知识兔div><dependencies>
23
知识兔div><dependency>
24
知识兔div><groupId>org.springframework.cloud</groupId>
25
知识兔div><artifactId>spring-cloud-dependencies</artifactId>
26
知识兔div><version>Finchley.SR2</version>
27
知识兔div><type>pom</type>
28
知识兔div><scope>import</scope>
29
知识兔div></dependency>
30
知识兔div></dependencies>
31
知识兔div></dependencyManagement>
- 创建启动类,注意,此处在启动类上的注解是@EnableDiscoveryClient
知识兔div>@EnableDiscoveryClient @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
71
知识兔div>2
知识兔div>3
知识兔div>public class Application {
4
知识兔div>public static void main(String[] args) {
5
知识兔div>SpringApplication.run(Application.class, args);
6
知识兔div>}
7
知识兔div>}
- 添加测试接口
知识兔div>@RestController @RequestMapping("/user") public class UserController { @GetMapping("/hello") public String sayHello(){ return "hello"; } }
91
知识兔div>2
知识兔div>"/user")
(3
知识兔div>public class UserController {
4
知识兔div>5
知识兔div>"/hello")
(6
知识兔div>public String sayHello(){
7
知识兔div>return "hello";
8
知识兔div>}
9
知识兔div>}
- 增加配置文件
知识兔div>server: port: 8081 spring: application: name: myEureka-Service eureka: client: #这次要注册到eureka上 register-with-eureka: true serviceUrl: defaulZone: "http://localhost:8761/eureka/" instance: #采用ip注册的方式 prefer-ip-address: true #id的格式 instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
181
知识兔div>server
2
知识兔div>port8081
3
知识兔div>4
知识兔div>spring
5
知识兔div>application
6
知识兔div>name myEureka-Service
7
知识兔div>8
知识兔div>eureka
9
知识兔div>client
10
知识兔div>#这次要注册到eureka上
11
知识兔div>register-with-eurekatrue
12
知识兔div>serviceUrl
13
知识兔div>defaulZone"http://localhost:8761/eureka/"
14
知识兔div>instance
15
知识兔div>#采用ip注册的方式
16
知识兔div>prefer-ip-addresstrue
17
知识兔div>#id的格式
18
知识兔div>instance-id $ spring.application.name $ spring.cloud.client.ip-address $ server.port
- 启动成功,去eureka看一下,发现了8762的服务
创建消费者
- 创建maven项目,eureka-consumer,添加相同依赖与启动类,但要更改配置文件
知识兔div>spring.application.name=eureka-client-article-service server.port=8082
21
知识兔div>spring.application.name=eureka-client-article-service
2
知识兔div>server.port=8082
- 使用RestTemplate获取Rest服务端调用接口
知识兔div>@Configuration public class BeanConfiguration { @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } }
71
知识兔div>@Configuration
2
知识兔div>public class BeanConfiguration {
3
知识兔div>@Bean
4
知识兔div>public RestTemplate getRestTemplate() {
5
知识兔div>return new RestTemplate();
6
知识兔div>}
7
知识兔div>}
- 创建接口
知识兔div>@RestController public class ArticleController { @Autowired private RestTemplate restTemplate; @GetMapping("/article /callHello") public String callHello() { return restTemplate.getForObject("http://localhost:8081/user/hello", String.class); } }
91
知识兔div>@RestController
2
知识兔div>public class ArticleController {
3
知识兔div>@Autowired
4
知识兔div>private RestTemplate restTemplate;
5
知识兔div>@GetMapping("/article /callHello")
6
知识兔div>public String callHello() {
7
知识兔div>return restTemplate.getForObject("http://localhost:8081/user/hello", String.class);
8
知识兔div>}
9
知识兔div>}
- 调用
- 改造
- 我们的目的是通过服务调用,而不要关心端口
- 改造 RestTemplate 的配置,添加一个 @LoadBalanced 注解,这个注解会自动构造 LoadBalancerClient 接口的实现类并注册到 Spring 容器中
知识兔div>@Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
91
知识兔div>@Configuration
2
知识兔div>public class RestTemplateConfig {
3
知识兔div>4
知识兔div>@Bean
5
知识兔div>@LoadBalanced
6
知识兔div>public RestTemplate getRestTemplate(){
7
知识兔div>return new RestTemplate();
8
知识兔div>}
9
知识兔div>}
- 接下来就是改造调用代码,我们不再直接写固定地址,而是写成服务的名称,这个名称就是我们注册到 Eureka 中的名称,是属性文件中的 spring.application.name
知识兔div>@GetMapping("/callHello") public String callHello() { return restTemplate.getForObject("http://myEureka-Service/user/hello", String.class); }
41
知识兔div>"/callHello")
(2
知识兔div>public String callHello() {
3
知识兔div>return restTemplate.getForObject("http://myEureka-Service/user/hello", String.class);
4
知识兔div>}
调用成功,舒服了
- 接下来就是改造调用代码,我们不再直接写固定地址,而是写成服务的名称,这个名称就是我们注册到 Eureka 中的名称,是属性文件中的 spring.application.name
- 使用RestTemplate获取Rest服务端调用接口
- 创建启动类,注意,此处在启动类上的注解是@EnableDiscoveryClient