文章目录
- 编写 Eureka 注册中心
- 创建服务的提供者
- 创建服务消费者
- 一、创建服务消费者并注册到 Eureka 中, 添加依赖
- 二、创建消费者的启动类
- 三、编写 application.yml 配置文件
- 四、创建配置类
- 五、创建 RestTemplate 的调用接口
- 六、访问 Eureka 控制台
- Eureka 安全问题
- Eureka 实现高可用
- Eureka 的自我保护模式
- 移除已经失效的服务信息
- 注册中心 application.yml 配置文件
- 客户端 application.yml 配置文件
Eureka
是Spring Cloud Netflix
中的一部分, 基于Netflix Eureka
做了二次封装, 主要是负责实现微服务架构中的服务治理工作,Eureka
是基于Rest
的服务, 提供了基于Java
的客户端组件, 能够非常方便的注册到Spring Cloud Eureka
中进行统一的处理
编写 Eureka 注册中心
一、创建模块, 取名 eureka-registry, 添加依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.john</groupId>
<artifactId>eureka-registry</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、创建启动类
@EnableEurekaServer
表示开启Eureka Server
package com.john.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
三、配置 application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
# 该应用为注册中心, 不需要想注册中心中注册自己
register-with-eureka: false
# 注册中心主要是维护服务实例, 不需要检索服务
fetch-registry: false
四、运行服务并访问 Eureka 的控制台
我们配置的
server.port
是8761
, 打开浏览器通过 http://localhost:8761/ 就可以访问Eureka
注册中心的控制台
创建服务的提供者
一、创建服务提供者并注册到 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.john</groupId>
<artifactId>eureka-client-user-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-client-user-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、创建提供者的启动类
package com.john.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientUserProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientUserProviderApplication.class, args);
}
}
三、编译 application.yml
完成
application.yml
之后就可以启动服务
server:
port: 8080
spring:
application:
name: eureka-client-user-provider
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://localhost:8761/eureka
instance:
# 采用 ip 方式注册
prefer-ip-address: true
# 定义实例 id 格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
四、创建 controller 给其他服务调用的接口
package com.john.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: CaoJun
* @Create: 2020-03-07 12:17
**/
@RestController
@RequestMapping("/provider")
public class HelloWorldController {
@GetMapping("/sayHello")
public String sayHello() {
return "Hello World";
}
}
五、再次访问注册中心
我们创建的服务提供者已经将自己的信息注册到
Eureka
注册中心中
创建服务消费者
一、创建服务消费者并注册到 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.john.consumer</groupId>
<artifactId>eureka-client-user-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-client-user-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、创建消费者的启动类
package com.john.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientUserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientUserConsumerApplication.class, args);
}
}
三、编写 application.yml 配置文件
server:
port: 8081
spring:
application:
name: eureka-client-user-consumer
四、创建配置类
- 主要是创建
RestTemplate
实例, 用于访问提供者服务@LoadBalanced
的功能是我们在 RestTemplate 进行远程调用的时候不用直接具体提供方的地址, 而是写提供方注册到Eureka
中的服务名称
package com.john.consumer.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Author: CaoJun
* @Create: 2020-03-07 12:13
**/
@Configuration
public class BeanConfiguration {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
五、创建 RestTemplate 的调用接口
在启动服务的时候, 通过访问 http://localhost:8081/consumer/sayHello 就可以通过消费方调用提供者方的服, 然后返回数据
package com.john.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @Author: CaoJun
* @Create: 2020-03-07 12:14
**/
@RestController
@RequestMapping("/consumer")
public class HelloWorldController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/sayHello")
public String sayHello( ) {
// return this.restTemplate
// .getForObject("http://localhost:8080/provider/sayHello", String.class);
return this.restTemplate
.getForObject("http://eureka-client-user-provider/provider/sayHello", String.class);
}
}
六、访问 Eureka 控制台
可以看到注册中心中注册了两个服务
Eureka 安全问题
在
Eureka
上自带了一个Web
的管理页面, 可以让我们去查询注册上的实例信息, 但是在实际的项目中, 直接访问Eureka
便能访问到, 这样会出现安全问题, 所以我们需要对Eureka
进行权限控制
一、在 Eureka Registry 模块中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
二、配置 application.yml
server:
port: 8761
spring:
application:
name: eureka-server
security:
user:
name: root
password: 123456
eureka:
client:
# 该应用为注册中心, 不需要想注册中心中注册自己
register-with-eureka: false
# 注册中心主要是维护服务实例, 不需要检索服务
fetch-registry: false
三、创建配置类
package com.john.eureka.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @Author: CaoJun
* @Create: 2020-03-07 14:36
**/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭 csrf
http.csrf().disable();
// 支持 httpBasic
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
Eureka 实现高可用
在生产环境下, 一台注册中心宕机, 那么整个系统就宕机了. 所以需要搭建一个集群来实现高可用
在Eureka
中是每一个Eureka
在配置文件中指定另外的n
个Eureka
地址列表即可
一、创建 eureka-registry-cluster
和
eureka-registry
一致, 只是配置application.yml
不太一样
二、引入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.john.eureka</groupId>
<artifactId>eureka-registry-cluster</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-registry-cluster</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、创建启动类
package com.john.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaRegistryClusterApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRegistryClusterApplication.class, args);
}
}
三、编写 application.yml 配置文件
spring:
application:
name: eureka-server-cluster
profiles:
# 使用指定的环境
active: slaveone
security:
user:
name: root
password: 123456
eureka:
client:
# 该应用为注册中心, 不需要想注册中心中注册自己
register-with-eureka: false
# 检索服务
fetch-registry: true
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
---
spring:
profiles: master
server:
port: 8761
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8762/eureka
---
spring:
profiles: slaveone
server:
port: 8762
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8761/eureka/
①、修改提供者和消费者的 application.yml 文件
提供者
server:
port: 8080
spring:
application:
name: eureka-client-user-provider
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
②、消费者
server:
port: 8081
spring:
application:
name: eureka-client-user-consumer
eureka:
client:
service-url:
defaultZone: http://root:123456@localhost:8762/eureka/, http://root:123456@localhost:8761/eureka/
③、启动 Eureka
注意:
- 在启动的时候需要修改配置文件
active: master/slave
方式, 当启动之后, 然后修改为另一种环境
四、最后启动服务提供者和服务消费者
目前所有的服务在
8761/8762
的注册中心注册了实例, 你会发现当你停止启动的一个服务后, 消费者也能够调用提供者的服务
Eureka 的自我保护模式
主要在一组客户端和 Eureka Server 之间存在网络分区场景下使用的, 当进入保护模式, Eureka Server 会尝试保护其服务注册表中的信息, 不再删除注册表中的信息, 在网络故障恢复之后,
Eureka Server
节点就会自动地退出保护模式
①、通过配置文件关闭保护模式
eureka:
server:
# 关闭自我保护模式
enable-self-preservation: false
移除已经失效的服务信息
在开发的时候, 我们有可能会不断地重启服务, 因为
Eureka
有自己的保护机制, 所以在节点下线后, 服务的信息还会一直存储在注册中心中, 可以在application.yml
中配置服务在Eureka
中的移除时间, 在生产环境推荐还是使用默认的
# 服务端配置
eureka:
server:
# 清理的间隔时间, 默认 6000
eviction-interval-timer-in-ms: 5000
# 客户端配置
eureka:
instance:
# 默认 30s, 客户端给服务端发送心跳的频率
lease-renewal-interval-in-seconds: 5
# 默认 90s, 服务端在上一次接收到客户端心跳后, 等待下一次心跳的超时时间, 在这个时间内还没接受到心跳, 就移除该客户端的实例
lease-expiration-duration-in-seconds: 5
注册中心 application.yml 配置文件
spring:
application:
# 服务的应用名称
name: eureka-server-cluster
profiles:
# 使用指定的环境
active: master
security:
# 配置 Eureka 注册中心的控制台权限
user:
name: root
password: 123456
eureka:
client:
# 该应用为注册中心, 不需要想注册中心中注册自己
register-with-eureka: false
# 检索服务
fetch-registry: true
instance:
prefer-ip-address: true
# 自定义 Eureka 的 instance-id, 主要是在控制台查看服务注册信息时能方便地查看哪些服务注册上了
# 例: eureka-client-user-consumer:192.168.73.1:8081
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
server:
# 关闭自我保护模式
enable-self-preservation: false
# 清理的间隔时间, 默认 6000
eviction-interval-timer-in-ms: 5000
# --- 表示分隔 yml 文件, 以下是另一个的环境配置信息
---
spring:
profiles: master
server:
port: 8761
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8762/eureka
---
spring:
profiles: slaveone
server:
port: 8762
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8761/eureka/
客户端 application.yml 配置文件
# 服务端口号
server:
port: 8080
spring:
application:
# 应用名称
name: eureka-client-user-provider
eureka:
client:
service-url:
# Eureka 注册中心的地址, 在启动的时候需要把自己的信息注册到注册中心中
defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
instance:
# 采用 ip 方式注册
prefer-ip-address: true
# 定义实例 id 格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
# 默认 30s, 客户端给服务端发送心跳的频率
lease-renewal-interval-in-seconds: 5
# 默认 90s, 服务端在上一次接收到客户端心跳后, 等待下一次心跳的超时时间, 在这个时间内还没接受到心跳, 就移除该客户端的实例
lease-expiration-duration-in-seconds: 5
- 如果还需要参考更多
Eureka
的配置可以看源码类org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean