I. Basic knowledge of Eureka

1. What is service governance

SpringCloud encapsulates the Eureka module developed by Netflix to implement service governance.

In the traditional RPC remote invocation framework, it is complicated to manage the dependencies between each service and services. Therefore, service governance is required to manage the dependencies between services, which can realize service invocation, load balancing, fault tolerance, and service discovery and registration.

2. What is service registration and discovery

Eureka adopts the CS design architecture. Eureka Server serves as the service registry. It is the service registry. Other microservices in the system use Eureka clients to connect to the Eureka Server and maintain heartbeat connections. In this way, the maintenance personnel of the system can use Eureka Server to monitor the normal operation of each microservice in the system.

In service Registry and Discovery, there is a registry. When a service is started, it registers its server information, such as the server address, to the registry in the form of an alias. Another party (consumer | service provider), in the form of an alias to the registry access to the actual service address, and then realize the local RPC calls RPC, remote invocation framework core design idea: lies in the registry, because use each service registry management and dependencies between services (service governance concept). In any RPC remote call framework, there is a registry that holds service address-related information (interface addresses).

3. Eureka two components

Eureka consists of two components: Eureka Server and Eureka Client

(1) Eureka Server provides service registration service

After microservice nodes are started, they are registered with the EurekaServer. In this way, the service registry of the EurekaServer stores information about all available service sections. The service node information can be directly viewed on the interface.

(2) Eureka Client is accessed through the registry

Eureka Is a Java client designed to simplify interactions with the Eureka Server. The client also has a built-in load balancer that uses the round-robin load algorithm. After the application starts, the heartbeat will be sent to the Eureka Server (default is 30 seconds). If the Eureka Server does not receive a heartbeat from a node within multiple heartbeat cycles, the Eureka Server removes the node from the service registry (default: 90 seconds).

2. Eureka construction procedure

1. Build preparations

(1) Create project Minhat-Cloud

  • Project name: Minhat-Cloud
  • Package name: cn. Minhat. Cloud

(2) Modify the POM file


      
<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>cn.minhat.cloud</groupId>
    <artifactId>minhat-cloud</artifactId>
    <version>1.0 the SNAPSHOT</version>
    <packaging>pom</packaging>

    <! -- Unified management of JAR packages -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>8.0.21</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <! - SpringBoot 2.2.2 -- -- >
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2. RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <! -- Spring Cloud Hoxton.SR1 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.2. RELEASE</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Copy the code

(3) Build database, build table and initialize data

-- Create database
CREATE DATABASE `minhat-cloud` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'

- create a table
CREATE TABLE `minhat-cloud`.`product_order` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'primary key',
  `product_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'Trade name',
  `price` bigint NOT NULL COMMENT 'Unit price',
  `status` int NOT NULL COMMENT 'Status, 1: paid, 2: unpaid'.PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Goods order';

-- Initialize data
INSERT INTO `minhat-cloud`.`product_order` (`id`, `product_name`, `price`, `status`) VALUES (1.'Java Programming Ideas'.9800.1);
INSERT INTO `minhat-cloud`.`product_order` (`id`, `product_name`, `price`, `status`) VALUES (2.'Java Virtual Machine '.7800.2);

Copy the code

2. Create the public module cloud-Commons

Common modules contain entity classes and common reverse classes

(1) Modify the POM file


      
<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>minhat-cloud</artifactId>
        <groupId>cn.minhat.cloud</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-commons</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
Copy the code

(2) Create entity class

/** * Goods order **@author Minhat
 */
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class ProductOrder {
    /** * Primary key */
    private Long id;
    /** * Name of commodity */
    private String productName;
    /** * Unit price */
    private Long price;
    /** * Status, 1: paid, 2: unpaid */
    private Integer status;
    
    public ProductOrder(String productName, Long price, Integer status) {
        this.productName = productName;
        this.price = price;
        this.status = status; }}/** * Public results return **@author Minhat
 */
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class CommonsResult<T> {
    private Integer code;
    private String msg;
    private T data;

    public CommonsResult(Integer code, String msg) {
        this.code = code;
        this.msg = msg; }}Copy the code

3. Create EurekaServer micro-service registry cloud-Eureka-Server

(1) Modify the POM file


      
<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>minhat-cloud</artifactId>
        <groupId>cn.minhat.cloud</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <! -- Eureka-Server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <! -- boot web actuator -->
        <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>
        <! -- General Configuration -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
Copy the code

(2), the change application. Yml

If there is no application.yml, create it yourself

server:
  port: 7001

# EurekaServer configuration
eureka:
  instance:
    # Eureka Server instance name
    hostname: localhost
  client:
    # false means not to register yourself with the registry
    register-with-eureka: false
    # false indicates that my side is the registry and my responsibility is to maintain the service instance, not to retrieve the service
    fetch-registry: false
    service-url:
      This address is required for both address query and registration services that interact with the Eureka Server
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

Copy the code

(3) Create the main startup class

EnableEurekaServer: EnableEurekaServer

/** * EurekaServer startup class * EnableEurekaServer: EnableEurekaServer **@author Minhat
 */
@SpringBootApplication
@EnableEurekaServer
public class CloudEurekaServer {
    public static void main(String[] args) { SpringApplication.run(CloudEurekaServer.class, args); }}Copy the code

(4) Start EurekaServer and view the monitoring interface

1> Start EurekaServer

2> View startup

Request:http://localhost:7001/

4, create EurekaClient order provider cloud-Eureka-order-client

(1) Modify the POM file


      
<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>minhat-cloud</artifactId>
        <groupId>cn.minhat.cloud</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-order-client</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <! -- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <! -- custom public modules -->
        <dependency>
            <groupId>cn.minhat.cloud</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <! -- Health Monitoring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
Copy the code

(2), the change application. Yml

server:
  port: 8001

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud-minhat? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(3) Create the main startup class

EnableEurekaClient: EnableEurekaClient

/** * Order micro service main start class **@author Minhat
 */
@SpringBootApplication
@EnableEurekaClient
public class CloudEurekaOrderClient {
    public static void main(String[] args) { SpringApplication.run(CloudEurekaOrderClient.class, args); }}Copy the code

(4) Create DAO interface and Mapper

The DAO interface:

/** * order DAO **@author Minhat
 */
@Mapper
public interface IProductOrderDao {

    /** * Insert order ** according to order entity diagram@paramProductOrder order *@returnReturns the number of rows affected */
    Integer insertByProductOrder(ProductOrder productOrder);

    /** * Query order by order ID **@paramId Order ID *@returnOrder * /
    ProductOrder selectByProductOrderId(long id);
}
Copy the code

Mapper:


      
<! DOCTYPEmapper PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.minhat.cloud.dao.IProductOrderDao">
    <resultMap id="BaseResultMap" type="cn.minhat.cloud.entities.ProductOrder">
        <id column="id" jdbcType="BIGINT" property="id"/>
        <result column="product_name" jdbcType="VARCHAR" property="productName"/>
        <result column="price" jdbcType="BIGINT" property="price"/>
        <result column="status" jdbcType="INTEGER" property="status"/>
    </resultMap>

    <sql id="Base_Column_List">
        `id`, `product_name`, `price`, `status`
    </sql>

    <insert id="insertByProductOrder" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="cn.minhat.cloud.entities.ProductOrder">
        insert into product_order(`product_name`, `price`, `status`)
        values (#{productName,jdbcType=VARCHAR}, #{price,jdbcType=BIGINT}, #{status,jdbcType=INTEGER})
    </insert>

    <select id="selectByProductOrderId" parameterType="java.lang.Long" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from product_order
        where id = #{id,jdbcType=BIGINT}
    </select>

</mapper>
Copy the code

(5) Create the Server layer

Server layer interface:

/** * Order Server interface **@author Minhat
 */
public interface IProductOrderServer {
    /** * Insert order ** according to order entity diagram@paramProductOrder order *@returnReturns the number of rows affected */
    Integer insertByProductOrder(ProductOrder productOrder);

    /** * Query order by order ID **@paramId Order ID *@returnOrder * /
    ProductOrder selectByProductOrderId(long id);
}

Copy the code

Server layer interface implementation:

/** * Order Server interface implementation class **@author Minhat
 */
@Service
public class ProductOrderServerImpl implements IProductOrderServer {
    @Autowired
    private IProductOrderDao productOrderDao;

    @Override
    public Integer insertByProductOrder(ProductOrder productOrder) {
        return productOrderDao.insertByProductOrder(productOrder);
    }

    @Override
    public ProductOrder selectByProductOrderId(long id) {
        returnproductOrderDao.selectByProductOrderId(id); }}Copy the code

(6) Create the Controller layer

/** * order Controller **@author Minhat
 */
@RestController
@RequestMapping("/order")
public class ProductOrderController {
    @Autowired
    private IProductOrderServer productOrderServer;

    @PostMapping("/add")
    public CommonsResult<ProductOrder> add(@RequestBody ProductOrder productOrder) {
        productOrderServer.insertByProductOrder(productOrder);
        return new CommonsResult<>(0."Add successful", productOrder);
    }

    @GetMapping("find/{id}")
    public CommonsResult<ProductOrder> find(@PathVariable Integer id) {
        ProductOrder productOrder = productOrderServer.selectByProductOrderId(id);
        return new CommonsResult<>(0."Query succeeded", productOrder); }}Copy the code

(7), test

1> Start the project

  1. Activation: cloud – eureka – server
  2. Activation: the cloud – eureka – order – the client

2. Access the Eureka monitoring page

Request:http://localhost:7001/

3> request the Controller’s interface

Request:http://localhost:8001/order/find/1

Request:http://localhost:8001/order/add

5. Create a cloud-eureka-consumer-client for EurekaClient

(1) Modify the POM file


      
<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>minhat-cloud</artifactId>
        <groupId>cn.minhat.cloud</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-consumer-client</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <! -- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <! -- custom public modules -->
        <dependency>
            <groupId>cn.minhat.cloud</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <! -- Health Monitoring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
Copy the code

(2), the change application. Yml

server:
  port: 80

spring:
  application:
    # Microservice name
    name: cloud-eureka-consumer-client

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka
Copy the code

(3) Create the main startup class

/** * Consumer Microservice Startup class *@author Minhat
 */
@SpringBootApplication
@EnableEurekaClient
public class CloudEurekaConsumerClient {
    public static void main(String[] args) { SpringApplication.run(CloudEurekaConsumerClient.class, args); }}Copy the code

(4) Add the configuration class

/** * configuration class **@author Minhat
 */
@Configuration
public class ApplicationContextConfig {
    @Bean
    public RestTemplate getRestTemplate(a) {
        return newRestTemplate(); }}Copy the code

(5) Create Controller

EnableEurekaClient: EnableEurekaClient

/** * Order consumer Controller **@author Minhat
 */
@RestController
@RequestMapping("/consumer/order")
public class ConsumerOrderController {
    public static final String PAYMENT_URL = "http://localhost:8001";

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/add")
    public CommonsResult<ProductOrder> add(@RequestBody ProductOrder productOrder) {
        CommonsResult<ProductOrder> commonsResult = restTemplate.postForObject(PAYMENT_URL + "/order/add/", productOrder, CommonsResult.class);
        return new CommonsResult<>(0."Add successful", commonsResult.getData());
    }

    @GetMapping("find/{id}")
    public CommonsResult<ProductOrder> find(@PathVariable Integer id) {
        return restTemplate.getForObject(PAYMENT_URL + "/order/find/"+ id, CommonsResult.class); }}Copy the code

(6), test

1> Start the project

  1. Activation: cloud – eureka – server
  2. Activation: the cloud – eureka – order – the client
  3. Activation: the cloud – eureka – consumer – client

2. Access the Eureka monitoring page

Request:http://localhost:7001/

3> Request the consumer Controller interface

Request:http://localhost:80/consumer/order/find/2 Request:http://localhost:80/consumer/order/add

3. Eureka cluster construction procedure

1. Eureka cluster principle

Problem: Micro service RPC remote call is the core of what high availability, imagine you have only one registry, if it fails, ha Ha ha ha O ( ̄)  ̄ O, will lead to the entire service environment is not available, so the solution is: build Eureka registry cluster, to achieve load balancing + fault tolerance

2. Modify the mapping configuration

findC:\Windows\System32\drivers\etcUnder the path ofhostsFile modificationThis configuration is to add the host mapping address

3. EurekaServer cluster configuration

(1) Add the application-7001.yml configuration file

server:
  port: 8001

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(2) Add the application-7002.yml configuration file

server:
  port: 8002

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(3) Pre-startup configuration

Click to configure the startup class: Configure the startup environment CloudeureKaserver-7001: Configure the startup environment CloudeureKaserver-7002:

(4), test

1> Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002

2. Access the Eureka monitoring page

Access: CloudEurekaServer – 7001 eureka7001.com:7001/

Access: CloudEurekaServer – 7002 eureka7002.com:7002/

4. EurekaClient order provider cloud-Eureka-order-client cluster

(1) Add the application-8001.yml configuration file

server:
  port: 8001

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(2) Add the application-8002.yml configuration file

server:
  port: 8002

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(3) Modify the Controller layer

/** * order Controller **@author Minhat
 */
@RestController
@RequestMapping("/order")
public class ProductOrderController {
    @Autowired
    private IProductOrderServer productOrderServer;
    @Value("${server.port}")
    private String serverPort;

    @PostMapping("/add")
    public CommonsResult<ProductOrder> add(@RequestBody ProductOrder productOrder) {
        productOrderServer.insertByProductOrder(productOrder);
        return new CommonsResult<>(0."Added successfully - Port:" + serverPort, productOrder);
    }

    @GetMapping("find/{id}")
    public CommonsResult<ProductOrder> find(@PathVariable Integer id) {
        ProductOrder productOrder = productOrderServer.selectByProductOrderId(id);
        return new CommonsResult<>(0.Query succeeded - Port:+ serverPort, productOrder); }}Copy the code

(4) Pre-startup configuration

Click to configure the startup class: Configure the startup environment CloudeureKaOrderClient-8001: Configure the startup environment CloudeureKaOrderClient-8002:

(5), test

1> Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002
  • CloudEurekaOrderClient-8001
  • CloudEurekaOrderClient-8002

2. Access the Eureka monitoring page

Access: CloudEurekaServer – 7001 eureka7001.com:7001/ Access: CloudEurekaServer – 7002 eureka7002.com:7002/

CloudEurekaOrderClient = CloudEurekaOrderClient = CloudEurekaOrderClient

Access: CloudEurekaOrderClient – 8001 Access: CloudEurekaOrderClient – 8002

5, EurekaClient end consumer cloud-Eureka-consumer-client call cluster order micro service

(1) Modify the configuration file application.yml

server:
  port: 80

spring:
  application:
    # Microservice name
    name: cloud-eureka-consumer-client

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
Copy the code

(2) Modify the ApplicationContextConfig configuration class

/** * configuration class **@author Minhat
 */
@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(a) {
        return newRestTemplate(); }}Copy the code

(3) Modify the ConsumerOrderController configuration class

/** * Order consumer Controller **@author Minhat
 */
@RestController
@RequestMapping("/consumer/order")
public class ConsumerOrderController {
    // public static final String PAYMENT_URL = "http://localhost:8001";
    public static final String PAYMENT_URL = "http://CLOUD-EUREKA-ORDER-CLIENT";

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("/add")
    public CommonsResult<ProductOrder> add(@RequestBody ProductOrder productOrder) {
        return restTemplate.postForObject(PAYMENT_URL + "/order/add/", productOrder, CommonsResult.class);
    }

    @GetMapping("find/{id}")
    public CommonsResult<ProductOrder> find(@PathVariable Integer id) {
        return restTemplate.getForObject(PAYMENT_URL + "/order/find/"+ id, CommonsResult.class); }}Copy the code

(5), test

1> Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002
  • CloudEurekaOrderClient-8001
  • CloudEurekaOrderClient-8002
  • CloudEurekaConsumerClient

2. Access the Eureka monitoring page

Access: CloudEurekaServer – 7001 eureka7001.com:7001/ Access: CloudEurekaServer – 7002 eureka7002.com:7002/

2 >, access CloudEurekaConsumerClient

First visit: Second visit: Third visit:

4. Improve the Actuator service information

1, EurekaClient side order provider cloud-Eureka-order-client configuration

(1) Modify the application-8001.yml configuration file

server:
  port: 8001

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  instance:
    # Host name: service name changed
    instance-id: cloud-eureka-order-client-8001
    Use the server'S IP address rather than the host name reported by the operating system
    prefer-ip-address: true

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

(2) Modify the application-8002.yml configuration file

server:
  port: 8002

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  instance:
    # Host name: service name changed
    instance-id: cloud-eureka-order-client-8002
    Use the server'S IP address rather than the host name reported by the operating system
    prefer-ip-address: true

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

2, test,

(1) Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002
  • CloudEurekaOrderClient-8001
  • CloudEurekaOrderClient-8002

(2) Access the Eureka monitoring interface

Access: CloudEurekaServer – 7001 eureka7001.com:7001/

V. Service Discovery

1, EurekaClient order provider cloud-Eureka-order-client modified

(1) Modify Controller

/** * order Controller **@author Minhat
 */
@RestController
@RequestMapping("/order")
public class ProductOrderController {
    private static final Logger log = LoggerFactory.getLogger(ProductOrderController.class);
    @Autowired
    private IProductOrderServer productOrderServer;
    @Value("${server.port}")
    private String serverPort;
    /** * Can normally be used for read operations on discovery services such as Netflix Eureka or Consul. IO */
    @Autowired
    private DiscoveryClient discoveryClient;

    @PostMapping("/add")
    public CommonsResult<ProductOrder> add(@RequestBody ProductOrder productOrder) {
        productOrderServer.insertByProductOrder(productOrder);
        return new CommonsResult<>(0."Added successfully - Port:" + serverPort, productOrder);
    }

    @GetMapping("find/{id}")
    public CommonsResult<ProductOrder> find(@PathVariable Integer id) {
        ProductOrder productOrder = productOrderServer.selectByProductOrderId(id);
        return new CommonsResult<>(0.Query succeeded - Port: + serverPort, productOrder);
    }

    @GetMapping("/discovery")
    public Object discovery(a) {
        // Get a known service ID
        List<String> services = discoveryClient.getServices();
        services.forEach(s -> log.info("Service ID: {}", s));
        services.forEach(s -> {
            List<ServiceInstance> instances = discoveryClient.getInstances(s);
            instances.forEach(serviceInstance -> {
                log.info("ServiceId: {} tInstanceId: {} tHost: {} tPort: {} tScheme: {}" ServiceId: {} tInstanceId: {}\tHost: {}\tPort: {}\ tScheme: {}, serviceInstance.getServiceId(), serviceInstance.getInstanceId(), serviceInstance.getHost(), serviceInstance.getPort(), serviceInstance.getScheme());
            });
        });
        returndiscoveryClient; }}Copy the code

(2) Modify the primary boot class

/** * Order micro service main start class **@author Minhat
 */
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class CloudEurekaOrderClient {
    public static void main(String[] args) { SpringApplication.run(CloudEurekaOrderClient.class, args); }}Copy the code

2, test,

(1) Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002
  • CloudEurekaOrderClient-8001
  • CloudEurekaOrderClient-8002
  • CloudEurekaConsumerClient

Wait a while after startup

(2), CloudEurekaOrderClient – 8001

http://localhost:8001/order/discovery Check the CloudeureKaOrderClient-8001 console

6. Eureka self-protection

1. Fault symptoms

The protection mode applies to the scenario where network partitions exist between a group of clients and EurekaServer. Once in protected mode, EurekaServer will attempt to protect the information in its service registry and will not delete any data in the service registry, i.e. no microservices will be deregistration.

If you see the following message on the home page of EurekaServer, Eureka enters the protected mode:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

2. Cause

(1) Why is Eureka self-protection mechanism generated?

To prevent The EurekaClient from running properly, but unlike the EurekaServer network, the EurekaServer does not immediately kick out the EurekaClient service.

(2) What is the self-protection mode

By default, if the EurekaServer does not receive a heartbeat from a microservice instance within a certain period of time, the EurekaServer will log the instance off (90 seconds by default). However, when the network partition fails (extension, lag, congestion), the microservice cannot communicate with the EurekaServer properly. This behavior may become very dangerous — because the microservice itself is healthy, the department should cancel the microservice at this time. Eureka solves this problem by using “self-protection mode” — when the EurekaServer node loses too many clients in a short period of time (possibly due to a network partition failure), the node goes into self-protection mode.

In self-protection mode, EurekaServer protects the information in the service registry and does not deregister any service instances.

His design philosophy is that it is better to keep the wrong service registration information than to blindly log out any potentially healthy service instance. A good death is better than a lazy life.

To sum up, self-protection mode is a security protection measure to deal with abnormal network. Its architectural philosophy is that it is better for colleagues to keep all microservices (both healthy and unhealthy microservices) than to blindly log off any healthy microservices. It is a self-protection mode that makes the Eureka cluster more robust and stable.

In a word: When a microservice is unavailable, Eureka will not immediately clean up, but will still save the information of the microservice to the AP branch in CAP

3. Eureka self-protection is prohibited

(1) EurekaServer configuration

Application – 7001. Yml:

server:
  port: 7001

# EurekaServer configuration
eureka:
  instance:
    # Eureka Server instance name
    hostname: eureka7001.com
  client:
    # false means not to register yourself with the registry
    register-with-eureka: false
    # false indicates that my side is the registry and my responsibility is to maintain the service instance, not to retrieve the service
    fetch-registry: false
    service-url:
      This address is required for both address query and registration services that interact with the Eureka Server
      defaultZone: http://eureka7002.com:7002/eureka/
  server:
    # Turn off the self-protection mechanism to ensure that unavailable services are kicked out in time
    enable-self-preservation: false
    # Kick out unavailable service interval milliseconds
    eviction-interval-timer-in-ms: 2000

Copy the code

Application – 7002. Yml:

server:
  port: 7002

# EurekaServer configuration
eureka:
  instance:
    # Eureka Server instance name
    hostname: eureka7002.com
  client:
    # false means not to register yourself with the registry
    register-with-eureka: false
    # false indicates that my side is the registry and my responsibility is to maintain the service instance, not to retrieve the service
    fetch-registry: false
    service-url:
      This address is required for both address query and registration services that interact with the Eureka Server
      defaultZone: http://eureka7001.com:7001/eureka/
  server:
    # Turn off the self-protection mechanism to ensure that unavailable services are kicked out in time
    enable-self-preservation: false
    # Kick out unavailable service interval milliseconds
    eviction-interval-timer-in-ms: 2000
Copy the code

(2) EurekaClient end order provider cloud-Eureka-order-client configuration

Application – 8001. Yml:

server:
  port: 8001

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  instance:
    # Host name: service name changed
    instance-id: cloud-eureka-order-client-8001
    Use the server'S IP address rather than the host name reported by the operating system
    prefer-ip-address: true
    # Eureka the interval between heartbeat messages sent by the client to the server, in seconds (default: 30 seconds)
    lease-renewal-interval-in-seconds: 1
    # Eureka Specifies the maximum amount of time a server can wait after receiving the last heartbeat, in seconds (default: 90 seconds)
    lease-expiration-duration-in-seconds: 2

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

Application – 8002. Yml:

server:
  port: 8002

spring:
  application:
    # Microservice name
    name: cloud-eureka-order-client
  datasource:
    # Current data source operation type
    type: com.alibaba.druid.pool.DruidDataSource
    # Mysql startup package
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/minhat-cloud? autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

eureka:
  client:
    # specifies whether to register yourself with EurekaServer
    register-with-eureka: true
    The default value is true. The default value is true. Clusters must be set to true if the Ribbon uses load balancing
    fetch-registry: true
    service-url:
      # Eureka cluster configuration
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  instance:
    # Host name: service name changed
    instance-id: cloud-eureka-order-client-8002
    Use the server'S IP address rather than the host name reported by the operating system
    prefer-ip-address: true
    # Eureka the interval between heartbeat messages sent by the client to the server, in seconds (default: 30 seconds)
    lease-renewal-interval-in-seconds: 1
    # Eureka Specifies the maximum amount of time a server can wait after receiving the last heartbeat, in seconds (default: 90 seconds)
    lease-expiration-duration-in-seconds: 2

mybatis:
  mapper-locations: classpath:mapper/*.xml
  # Package where all Entity aliases reside
  type-aliases-package: com.atguigu.springcloud.entities
Copy the code

4, test,

(1) Start the project

  • CloudEurekaServer-7001
  • CloudEurekaServer-7002
  • CloudEurekaOrderClient-8001
  • CloudEurekaOrderClient-8002

(2) Access the Eureka health interface

eureka7001.com:7001/

(3) Close CloudeureKaOrderClient-8002 and check the health page again