SpringCloud Microservice Governance I (Введение, Создание среды, Эврика)
SpringCloud Micrevice Manuervice II (Роббин, Hystix, Figage)
Управление микросервисом SpringCloud 3 (шлюз Zuul)
1. Метод удаленного вызова
Узнайте, как вызывать микросервисы
1.1.RPC
RPC, или удаленный вызов процедур, представляет собой компьютерный протокол связи. Протокол позволяет программе, работающей на одном компьютере, вызывать подпрограмму на другом компьютере без необходимости дополнительного программирования этого взаимодействия программистом.
1.2.Http
Http-протокол: протокол передачи гипертекста — это протокол прикладного уровня.
2. Инструменты HTTP-клиента
2.1 Spring RestTemplate
Spring предоставляет класс инструментов шаблона RestTemplate, который инкапсулирует клиенты на основе Http и реализует сериализацию и десериализацию объектов и json, что очень удобно. RestTemplate не ограничивает клиентский тип Http, а абстрагирует его.В настоящее время поддерживаются три часто используемых типа:
- HttpClient
- OkHttp
- Собственный URLConnection JDK (по умолчанию)
Сначала зарегистрируйтесь в проектеRestTemplate
объект, который можно зарегистрировать в расположении класса запуска:
@SpringBootApplication
public class HttpDemoApplication {
public static void main(String[] args) {
SpringApplication.run(HttpDemoApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
// 默认的RestTemplate,底层是走JDK的URLConnection方式。
return new RestTemplate();
}
}
непосредственно в тестовом классе@Autowired
впрыск:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = HttpDemoApplication.class)
public class HttpDemoApplicationTests {
@Autowired
private RestTemplate restTemplate;
@Test
public void httpGet() {
User user = this.restTemplate.getForObject("http://localhost/hello", User.class);
System.out.println(user);
}
}
Далее следует формальное введение в микросервисы.
3.SpringCloud
3.1 Введение
SpringCloud — один из проектов Spring.Адрес официального сайта: http://projects.spring.io/spring-cloud/
SpringCloud интегрирует некоторые из очень популярных сейчас технологий и реализует такие функции, как: управление конфигурацией, обнаружение сервисов, интеллектуальная маршрутизация, балансировка нагрузки, автоматические выключатели, управляющая шина, состояние кластера и так далее. К основным задействованным компонентам относятся:
netflix
- Эврика: Реестр
- Зуул: Сервисный шлюз
- Лента: балансировка нагрузки
- Feign: Service Call
- Хистикс: Предохранитель
Далее мы изучим важные компоненты Spring Cloud один за другим.
4. Моделирование сценария микросервиса
Во-первых, нам нужно смоделировать сценарий вызова службы. Микросервисную архитектуру удобно изучать позже
4.1. Поставщики услуг
Мы создаем новый проект для предоставления служб запросов внешних пользователей.
4.1.1 Проект создания пружинных лесов
Зависимости также были автоматически импортированы:
<?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.leyou.demo</groupId>
<artifactId>user-service-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>user-service-demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Конечно, поскольку мы хотим использовать общий преобразователь, нам нужно вручную добавить зависимость:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
Очень быстро!
4.1.2 Написание кода
Добавьте внешний интерфейс запроса:
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return this.userService.queryById(id);
}
}
Услуга:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id) {
return this.userMapper.selectByPrimaryKey(id);
}
}
mapper:
@Mapper
public interface UserMapper extends tk.mybatis.mapper.common.Mapper<User>{
}
Класс сущности:
@Table(name = "tb_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 创建时间
private Date created;
// 更新时间
private Date updated;
// 备注
private String note;
// 。。。省略getters和setters
}
Файл свойств, здесь мы используем синтаксис yaml вместо свойств:
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb01
username: root
password: 123
hikari:
maximum-pool-size: 20
minimum-idle: 10
mybatis:
type-aliases-package: com.leyou.userservice.pojo
4.2. Звонящие в службу поддержки
4.2.1 Создать проект
Как и выше, следует отметить, что мы вызываем функцию user-service, поэтому нет необходимости в зависимостях, связанных с mybatis.
пом:
<?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.leyou.demo</groupId>
<artifactId>user-consumer-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>user-consumer-demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 添加OkHttp支持 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.2.2. Написать код
Впервые зарегистрировался в стартап-классеRestTemplate
:
@SpringBootApplication
public class UserConsumerDemoApplication {
@Bean
public RestTemplate restTemplate() {
// 这次我们使用了OkHttp客户端,只需要注入工厂即可
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
Удаленно запросить интерфейс в user-service-demo через RestTemplate:
@Component
public class UserDao {
@Autowired
private RestTemplate restTemplate;
public User queryUserById(Long id){
String url = "http://localhost:8081/user/" + id;
return this.restTemplate.getForObject(url, User.class);
}
}
Затем напишите user-service и запросите информацию UserDAO в цикле:
@Service
public class UserService {
@Autowired
private UserDao userDao;
public List<User> querUserByIds(List<Long> ids){
List<User> users = new ArrayList<>();
for (Long id : ids) {
User user = this.userDao.queryUserById(id);
users.add(user);
}
return users;
}
}
Напишите контроллер:
@RestController
@RequestMapping("consume")
public class ConsumerController {
@Autowired
private UserService userService;
@GetMapping
public List<User> consume(@RequestParam("ids") List<Long> ids) {
return this.userService.queryUserByIds(ids);
}
}
4.3 Вопросы?
- В потребителе мы жестко закодировали URL-адрес в коде, что неудобно для последующего обслуживания.
- Потребителю необходимо запомнить адрес пользовательского сервиса, в случае изменения его могут не уведомить и адрес будет недействительным.
- Потребитель не знает ни статуса пользовательской службы, ни того, что служба не работает.
- user-service имеет только одну службу и не имеет высокой доступности
- Даже если пользовательская служба образует кластер, потребителям все равно необходимо самостоятельно реализовать балансировку нагрузки.
На самом деле проблемы, упомянутые выше, можно обобщить как проблемы, с которыми приходится сталкиваться распределенным сервисам:
- Управление услугами
- Как автоматически зарегистрироваться и узнать
- Как осуществлять государственный надзор
- Как реализовать динамическую маршрутизацию
- Как сервисы достигают балансировки нагрузки
- Как сервис решает проблему аварийного восстановления
- Как добиться единой конфигурации сервисов
Ответы на поставленные выше вопросы мы получим в SpringCloud.
5. Реестр Эврика
5.1 Схема
Базовая архитектура:
- Эврика: это сервисный реестр (который может быть кластером), раскрывающий свой собственный адрес внешнему миру.
- Провайдер: зарегистрируйте свою информацию (адрес, какую услугу предоставлять) в Eureka после запуска.
- Потребитель: Подпишитесь на Eureka для получения услуги, Eureka отправит список всех адресов поставщиков соответствующей услуги потребителю и регулярно обновит его.
- Heartbeat (обновление): провайдер периодически обновляет свой статус до Eureka через http.
5.2. Вводный случай
5.2.1. Написание EurekaServer
Далее создаем проект, запускаем EurekaServer:
По-прежнему используйте инструмент быстрой сборки, предоставленный Spring, выберите зависимости:
Полный файл 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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.leyou.demo</groupId>
<artifactId>eureka-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- SpringCloud版本,是最新的F系列 -->
<spring-cloud.version>Finchley.RC1</spring-cloud.version>
</properties>
<dependencies>
<!-- Eureka服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- SpringCloud依赖,一定要放到dependencyManagement中,起到管理版本的作用即可 -->
<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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
Напишите класс запуска:
@SpringBootApplication
@EnableEurekaServer // 声明这个应用是一个EurekaServer
public class EurekaDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDemoApplication.class, args);
}
}
Напишите конфигурацию:
server:
port: 10086 # 端口
spring:
application:
name: eureka-server # 应用名称,会在Eureka中显示
eureka:
client:
register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
fetch-registry: false # 是否拉取其它服务的信息,默认是true
service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
defaultZone: http://127.0.0.1:${server.port}/eureka
Запустите службу и получите доступ:http://127.0.0.1:10086/eureka
5.2.2 Зарегистрируйте пользовательский сервис в Eureka
Регистрация службы заключается в добавлении клиентских зависимостей Eureka к службе, а клиентский код автоматически регистрирует службу в EurekaServer.
Мы добавляем клиентские зависимости Eureka в user-service-demo:
Сначала добавьте зависимости SpringCloud:
<!-- SpringCloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Spring的仓库地址 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
Затем клиент Eureka:
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Включите клиентскую функцию Eureka в классе запуска.
добавлением@EnableDiscoveryClient
Чтобы открыть клиентскую функцию Eureka
@SpringBootApplication
@EnableDiscoveryClient // 开启EurekaClient功能
public class UserServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceDemoApplication.class, args);
}
}
записать конфигурацию
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb01
username: root
password: 123
hikari:
maximum-pool-size: 20
minimum-idle: 10
application:
name: user-service # 应用名称
mybatis:
type-aliases-package: com.leyou.userservice.pojo
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
Уведомление:
- Здесь мы добавили свойство spring.application.name для указания имени приложения, которое в дальнейшем будет использоваться в качестве идентификатора приложения.
- Не указывайте register-with-eureka и fetch-registry, потому что значение по умолчанию — true.
Перезапустите проект и посетите страницу мониторинга Eureka http://127.0.0.1:10086/eureka для просмотра.
Мы обнаружили, что служба обслуживания пользователей была успешно зарегистрирована.
5.2.3 Потребители получают услуги от Eureka
Далее мы модифицируем Consumer-Demo и пытаемся получить сервис от EurekaServer.
Метод аналогичен потребителю, нужно только добавить в проект зависимости EurekaClient, а информацию можно получить через имя сервиса!
1) Добавьте зависимости:
Сначала добавьте зависимости SpringCloud:
<!-- SpringCloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Spring的仓库地址 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
Затем клиент Eureka:
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2) Откройте клиент Eureka в классе запуска
@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
public class UserConsumerDemoApplication {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
3) Измените конфигурацию:
server:
port: 8080
spring:
application:
name: consumer # 应用名称
eureka:
client:
service-url: # EurekaServer地址
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true # 当其它服务获取地址时提供ip而不是hostname
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
4) Измените код и используйте метод класса DiscoveryClient для получения экземпляра службы по имени службы:
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;// Eureka客户端,可以获取到服务实例信息
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>();
// String baseUrl = "http://localhost:8081/user/";
// 根据服务名称,获取服务实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
// 因为只有一个UserService,因此我们直接get(0)获取
ServiceInstance instance = instances.get(0);
// 获取ip和端口信息
String baseUrl = "http://"+instance.getHost() + ":" + instance.getPort()+"/user/";
ids.forEach(id -> {
// 我们测试多次查询,
users.add(this.restTemplate.getForObject(baseUrl + id, User.class));
// 每次间隔500毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return users;
}
}
5.4. Продвинутая Эврика
5.4.1 Высокодоступный сервер Eureka
Eureka Server - это сервисный реестр. В данном случае у нас есть только один EurekaServer. Фактически, EurekaServer также может быть кластером для формирования высокодоступного центра Eureka.
Начните создавать высокодоступный EurekaServer
Предположим, что мы хотим построить два кластера EurekaServer, порты: 10086 и 10087.
1) Модифицируем исходную конфигурацию EurekaServer:
server:
port: 10086 # 端口
spring:
application:
name: eureka-server # 应用名称,会在Eureka中显示
eureka:
client:
service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
defaultZone: http://127.0.0.1:10087/eureka
На самом деле, по так называемой высокой доступности, на самом деле, сам Eurekaserver зарегистрирован в качестве службы, сможет найти друг друга друг с другом таким образом, чтобы несколько Eurekaserver, чтобы сформировать кластер. Таким образом, мы сделали следующие изменения:
- Удалены register-with-eureka=false и fetch-registry=false. Поскольку значение по умолчанию равно true, он зарегистрируется в реестре.
- Измените значение service-url на адрес другого EurekaServer вместо себя.
2) Другая конфигурация прямо противоположна:
server:
port: 10087 # 端口
spring:
application:
name: eureka-server # 应用名称,会在Eureka中显示
eureka:
client:
service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
defaultZone: http://127.0.0.1:10086/eureka
Примечание: Приложение в идее не может быть запущено дважды, нам нужно перенастроить лаунчер:
Затем запустите его.
3) Запустите тест:
4) Клиент регистрирует службу в кластере
Поскольку существует более одного Eurekaserver, при регистрации сервиса параметр службы-URL должен быть изменен:
eureka:
client:
service-url: # EurekaServer地址,多个地址以','隔开
defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
5.4.2. Поставщики услуг
Поставщику услуг необходимо зарегистрировать услугу на EurekaServer и завершить обновление услуги и другую работу.
регистрация службы
Когда сервис-провайдер запустится, он обнаружит свойства конфигурации:eureka.client.register-with-erueka=true
Верен ли параметр, на самом деле значение по умолчанию истинно. Если значение равно true, он инициирует запрос Rest к EurekaServer со своими собственными метаданными, и Eureka Server сохранит эту информацию в двухуровневой структуре карты. Ключ Карты первого уровня — это имя службы, а ключ Карты второго уровня — идентификатор экземпляра службы.
Продление услуги
После того, как служба регистрации будет завершена, поставщик услуг будет поддерживать пульс (регулярно инициирует запрос Rest к EurekaServer) и сообщает EurekaServer: «Я все еще жив». Это мы называем возобновлением службы;
Есть два важных параметра, которые изменяют поведение продления службы:
eureka:
instance:
lease-expiration-duration-in-seconds: 90
lease-renewal-interval-in-seconds: 30
- Lease-renewal-interval-in-seconds: интервал обновления услуги (обновления), по умолчанию 30 секунд.
- Lease-expiration-duration-in-seconds: время истечения срока службы, значение по умолчанию — 90 секунд.
То есть по умолчанию каждые 30 секунд служба будет отправлять пульс в реестр, чтобы доказать, что он жив. Если в течение более 90 секунд не будет отправлено сердцебиение, EurekaServer будет считать, что служба не работает, и будет удалена из списка служб.Эти два значения не должны изменяться в производственной среде, и значений по умолчанию достаточно.
Но во время разработки это значение слишком велико.Часто, когда мы отключаем службу, мы обнаруживаем, что Eureka все еще думает, что служба жива. Таким образом, мы можем настроить его соответствующим образом на этапе разработки.
eureka:
instance:
lease-expiration-duration-in-seconds: 10 # 10秒即过期
lease-renewal-interval-in-seconds: 5 # 5秒一次心跳
идентификатор экземпляра
Сначала посмотрите на информацию о статусе службы:
На странице мониторинга Eureka просмотрите информацию о регистрации службы:
В столбце состояния отображается следующая информация:
- UP(1): указывает, что сейчас запущен 1 экземпляр, кластера нет.
- DESKTOP-2MVEC12:user-service:8081: имя экземпляра (идентификатор экземпляра),
- Формат по умолчанию:
${hostname} + ${spring.application.name} + ${server.port}
- instance-id — единственный критерий для различения разных экземпляров одной и той же службы, поэтому его нельзя повторять.
- Формат по умолчанию:
Мы можем изменить его состав через атрибут instance-id:
eureka:
instance:
instance-id: ${spring.application.name}:${server.port}
Перезапустите службу и повторите попытку:
5.4.3 Потребители услуг
Получить список услуг
Обнаружено при запуске потребителя службыeureka.client.fetch-registry=true
Значение параметра, если оно истинно, будет скопировано только для чтения из списка служб Eureka Server, а затем кэшировано локально. и每隔30秒
Данные будут получены и обновлены. Мы можем модифицировать его по следующим параметрам:
eureka:
client:
registry-fetch-interval-seconds: 5
В производственной среде нам нужно изменить это значение.
Но для того, чтобы быстро получить последний статус сервиса в среде разработки, мы можем установить его на меньший размер.
5.4.4 Отказоустойчивость и самозащита
отказ от отказа
Иногда наш поставщик услуг может не работать в обычном режиме, а служба может работать со сбоями из-за переполнения памяти, сбоя сети и т. д. Eureka Server необходимо удалить такие службы из списка служб. Таким образом, он будет запускать запланированную задачу для удаления всех отказавших служб (не отвечающих более 90 секунд) каждые 60 секунд.
в состоянии пройтиeureka.server.eviction-interval-timer-in-ms
Измените параметры, единица измерения — миллисекунды, и не изменяйте среду генерации.
Это внесет большие изменения в нашу разработку.Вы перезапускаете сервис, и Эврика ответит через 60 секунд. Стадия разработки может быть скорректирована соответствующим образом, например, 10S
самозащита
Когда мы закроем службу, мы увидим предупреждение на панели Eureka:
Это запускает механизм самозащиты Эврики. Если службе не удается вовремя обновить пульс, Eureka подсчитывает, превышает ли доля экземпляров службы, у которых произошел сбой пульса за последние 15 минут, 85 %. В производственной среде из-за сетевых задержек и других причин доля экземпляров сбоя пульса, вероятно, превысит стандарт, но в настоящее время нецелесообразно удалять службу из списка, поскольку служба может быть недоступна. Eureka защитит регистрационную информацию текущего экземпляра и не удалит ее. Это хорошо работает в производственной среде, обеспечивая доступность большинства сервисов.
Но это приносит проблемы в нашу разработку, поэтому отключим режим самозащиты на этапе разработки:
eureka:
server:
enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)