SpringCloud-2020.0. Easy to get started with version 3

Spring Cloud 2020.0. Version 0 Beijing time 2020.12 22 release, completely removed all components of Netflix except Eureka, and supported springboot 2 4.x

Netflix component alternatives (Feign can still be used, OpenFiegn as a REST client)

NetflixRecommended alternativesexplain
HystrixResilience4jHystrix also recommends you to use it instead of yourself
Hystrix Dashboard / TurbineMicrometer + Monitoring SystemMonitoring is left to more professional components
RibbonSpring Cloud LoadbalancerSpring did it himself
Zuul 1Spring Cloud GatewaySpring did it himself
Archaius 1Spring Boot externalized configuration + Spring Cloud configurationBetter and more powerful than Netflix

Here I briefly recorded spring cloud 2020 In the case of version 0.3, as a learning for future reference, SpringCloud will use SpringCloud Alibaba in the future.

Eureka service registration and discovery

1, Overview

Eureka official website

Eureka Chinese website

1. CAP principle

CAP principle, also known as CAP theorem, refers to Consistency, Availability and Partition tolerance in a distributed system. However, these three elements can only achieve two points at most, and it is impossible to give consideration to the three. Generally speaking, AP and CP.

2. Introduction to Eureka

Eureka is a REST based service, which is used to locate services to achieve the purpose of load balancing and middle tier service failover. Spring cloud integrates it into its sub project spring cloud Netflix to realize the service registration and discovery functions of spring cloud. The function is similar to Dubbo's registry, such as Zookeeper. Eureka consists of two components: Eureka Server and Eureka Client.

  • Eureka Server: a service registry (which can be a cluster) that exposes its own address
  • Service Provider: a micro service (java program or python) that registers its own information (address, etc.) with Eureka after startup
  • Service Consumer: subscribe to the service from Eureka. Eureka will send the address list of all providers of the corresponding service to consumers and update it regularly
  • Heartbeat (renewal): the provider periodically updates its status to Eureka through http
  • By default, when Eureka does not receive the heartbeat sent by the service provider after 90 seconds, it will recognize that the service is dead and log off the service. Logout here is not immediate, but centralized logout of services that "die" in this interval after 60 seconds. If you log off immediately, it will inevitably cause a great burden on Eureka. These time parameters can be customized
  • Self protection mechanism: if more than 85% of the nodes do not have a normal heartbeat within 15 minutes, Eureka thinks that there is a network failure between the client and the registry, so it will not receive the heartbeat or delete the service.

2, Service Construction

1. Create parent-child aggregation project

In the parent project POM XML import dependency

<spring-cloud.version>2.5.2</eureka.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>

        <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>

2. Establishment of Eureka registry

Create the springboot module and introduce the service registration service

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    <!--There may be springboot of tomcat jar Package conflict, so remove;
	In addition, there may be jar The package cannot be found. Enter layer by layer and find the wrong one jar Package version. Just import the correct version
    <exclusions>
        <exclusion>
            <artifactId>servlet-api</artifactId>
            <groupId>javax.servlet</groupId>
        </exclusion>
    </exclusions>-->
</dependency>

Enter application YML file modification configuration

server:
  port: 8088
spring:
  application:
    name: eureka-server
# eureka configuration
eureka:
  #Instance name of eureka server
  instance:
    hostname: localhost
  server:
    ## Start the self-protection mode (when the service is stopped, eureka will not immediately clear the stopped services, so false)
    enable-self-preservation: false
    # Clean up invalid nodes. The default is 60 * 1000 milliseconds, i.e. 60 seconds
    eviction-interval-timer-in-ms: 5000
  client:
    #Whether to register yourself with Eureka server. It is a server and does not need to be registered
    register-with-eureka: false
    #false means that my client is the registry. My responsibility is to maintain service instances and I don't need to retrieve services
    fetch-registry: false
    service-url:
      #Setting the address query service and registration service interacting with Eureka server need to rely on this defaultzone address. If it is a cluster, it needs to add the addresses of other servers.
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

Finally, add the @ EnableEurekaServer annotation on the startup class

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
}

Start localhost:8088 to enter my registry

  • System Status: system information
  • DS Replicas: server replicas
  • Instances currently registered with Eureka: list of registered microservices
  • General Info: general information
  • Instance Info: instance information

3. Create Provider service

Create a new springboot module and introduce dependencies

<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-web</artifactId>
</dependency>

Enter application YML file modification configuration

server:
  port: 8080
spring:
  # Do not underline the application name, otherwise the service will not be found
  application:
    name: student
eureka:
  client:
    #EurekaServer address
    service-url:
      #Multiple cluster configurations
      defaultZone: http://localhost:8088/eureka
    #Service registration: whether to register with the server. The default value is true
    register-with-eureka: true
  instance:
    #Composition information of service provider instance
    instance-id: ${spring.application.name}:${server.port}
    # When getHostname is called to get the hostname of the instance, the ip is returned instead of the host name
    prefer-ip-address: true
    # Specify your own ip information. If you don't specify it, you will find it yourself
    # ip-address: 127.0.0.1
    #The maximum waiting time of Eureka server after receiving the last heartbeat, in seconds. If it exceeds, it will be rejected (the client tells the server to wait for itself according to this rule). The default is 90
    lease-expiration-duration-in-seconds: 20
    #Heartbeat packet, default 30
    lease-renewal-interval-in-seconds: 10

Create a server-side service

@RestController
public class HelloController {
    
    @GetMapping("/")
    public String hello() {
        return "hello,world!s";
    }
}

Finally, add @ EnableEurekaClient to the startup class to join the registry

For web programs developed in python, you can also register in Eureka registry. Here I will take the Flask framework as an example

from flask import Flask
from py_eureka_client import eureka_client
from flask_cors import *

def setEureka():
    server_host = "localhost"
    server_port = 5000
    eureka_client.init(eureka_server="http://localhost:8088/eureka",
                       #Underline is not allowed
                       app_name="flaskServer",
                       # Host name of the current component, optional parameter. If it is not filled in, it will be calculated automatically. If the service and eureka server are deployed on the same machine, it must be filled in. Otherwise, it will be calculated as 127.0 zero point one
                       instance_host=server_host,
                       instance_port=server_port,
                       # High availability policy when calling other services. Optional. The default is random
                       ha_strategy=eureka_client.HA_STRATEGY_RANDOM)

setEureka()
# Cross domain configuration
CORS(app, supports_credentials=True)

@app.route('/')
def index():
    return 'hello world'

if __name__ == '__main__':
    app.debug = True
    app.run()

Start accessing localhost:5000, which can be accessed normally. Here, it is used as a Provider

4. Establish Consumer

Replace the ribbon with the Spring Cloud Loadbalancer. You can customize the load balancing algorithm. Polling is the default here. Through @ LoadBalanced, the bottom layer of the program will resolve the registered service name into specific ip and port through the ribbon by default, and finally make an access request.

Reference documents.

Create springboot module and introduce 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-web</artifactId>
</dependency>

Enter application YML file modification configuration

server:
  port: 8081
spring:
  application:
    name: Consumer
eureka:
  client:
    service-url:
      # EurekaServer address. Multiple addresses are separated by ','
      defaultZone: http://localhost:8088/eureka
    #Service registration: whether to register with the server. The default value is true
    register-with-eureka: false

Add annotations to the startup class

@SpringBootApplication
// It will be registered in the registry upon startup
@EnableEurekaClient
@EnableDiscoveryClient
public class ConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ApiApplication.class, args);
	}

	   @Bean
    // To enable load balancing, you must
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        //Can customize
        return builder
                .setConnectTimeout(Duration.ofMillis(100))
                .setReadTimeout(Duration.ofMillis(500))
                .build();
    }
}

Finally, create Cntroller and call the service remotely

@RestController
@Slf4j
public class ApiController {

    @Autowired
    RestTemplate restTemplate;

    //The package cited here is org springframework. cloud. client. discovery. DiscoveryClient
    @Autowired
    DiscoveryClient discoveryClient;

    @GetMapping("/")
    public Object discory(){
        Object template = restTemplate.getForObject("http://STUDENT/",Object.class);
        return template;
    }

    @GetMapping("/py")
    public String discory1(){
        String template = restTemplate.getForObject("http://FLASKSERVER/",String.class);
        return template;
    }
    @GetMapping("/test")
    public String discory2(){
        log.info("Trying to get registry information");
        log.info("getApplications"+discoveryClient.getServices());
        log.info("getInstancesById"+discoveryClient.getInstances("STUDENT"));
        return "success";
    }

}

After startup, you can access the services provided by 8080 and flash server through port 8081

5. Optimization and improvement

For Eureka, info, cluster, zone, region, etc

OpenFeign load balancing

1, Overview

Compared with Ribbon+RestTemplate, its operation is too cumbersome. It has been simply stated in the above section that it can simplify development through OpenFeign.

OpenFeign is a declarative http client, which makes it very easy to write a web service client. You only need to create an interface and add annotations on the interface. At the bottom layer, OpenFeign integrates the Ribbon and uses the Ribbon to maintain the service list information of springcloud Dept. the interface will automatically request the corresponding services through http. It replaces RestTemplate and has low performance, but can make the code readable.

The predecessor of OpenFeign is Feign, which has stopped. OpenFeign is a spring cloud that supports the annotation of Spring MVC on the basis of Feign, and generates implementation classes through dynamic proxy to do load balancing and call other services.

Spring cloud official documentation

2, Service Construction

1. Multi module load balancing

In the POM of the consumer module XML add dependency

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

There is an interface in the student module

@GetMapping("/")
public String hello() {
    System.out.println("Call succeeded");
    return "hello,world!s";
}

Open Feign annotation in consumer module

@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
@EnableFeignClients(basePackages = "com.zstu.consumer")
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    // To enable load balancing, you must
    @LoadBalanced
    public RestTemplate restTemplate(){
    	return new RestTemplate();
    }
}

Create a Feign interface class, and add the service name requiring remote access on the class. The method is the interface exposed by the service

@FeignClient(value = "student")
public interface FeignService {
    //What is called here is the student's helloworld method
    @GetMapping("/")
    String hello();
}

Finally, add a new method in the controller, call this method, and start the project to call it internally and remotely

@Autowired
private FeignService feignService;

@GetMapping("/test111")
public String test(){
    feignService.hello();
    return "success";
}

2. Optimization and improvement

resilience4j can be used for service fusions and downgrades, but there don't seem to be many online practical materials. I plan to go directly to sentinel next time.

Spring Cloud Gateway

1, Overview

API Gateway (APIGW / API Gateway), as its name suggests, is an API oriented, serial and centralized strong control service that appears on the system boundary. The boundary here is the boundary of the enterprise IT system. It can be understood as an enterprise application firewall, which mainly plays the role of isolating external access from internal systems.

Spring cloud gateway Chinese website

SpringCloudGateway official website

Spring Cloud Gateway is the second-generation gateway framework officially launched by Spring Cloud, replacing Zuul gateway. As the of traffic, gateway plays a very important role in microservice system. The common functions of gateway include routing forwarding, permission verification, current limit control and so on. It also has the following characteristics:

  • Based on Spring 5, reactor (pattern) and SpringBoot 2.0
  • Ability to match routes on any request attribute
  • Assertions and filters are route specific
  • Hystrix circuit breaker integration
  • SpringCloud DiscoveryClient integration
  • Easy to write assertions and filters
  • Request rate limit
  • Path rewriting

2, Service Construction

1. Gateway gateway construction

Inherit Eureka configuration

Create a new springboot module, which I call api here, and introduce dependency

 <!-- spring cloud gateway rely on -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

There is a jar package conflict between Gateway and SpringBoot Web in spring cloud, so I did not introduce SpringBoot Web dependency here

Configure application YML profile

server:
  port: 8081
spring:
  application:
    name: Api
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #Enable automatic forwarding according to the micro service name
          lower-case-service-id: true  #The microservice name is rendered in lowercase

      routes:
      - id: student           # The routing id has no fixed rules. It is recommended to match the service name
        uri: lb://STUDENT
        predicates:
        - Path=/**    # Assertion: route with path matching
      - id: flaskserver           # The routing id has no fixed rules. It is recommended to match the service name
        uri: http://localhost:5000 # matches the routing address of the service
        predicates:
            - Path=/**    # Assertion: route with path matching

eureka:
  client:
    service-url:
      # EurekaServer address. Multiple addresses are separated by ','
      defaultZone: http://localhost:8088/eureka
    #Service registration: whether to register with the server. The default value is true
	#register-with-eureka: false
  instance:
    #Composition information of service provider instance
    instance-id: ${spring.application.name}:${server.port}

Add the annotation @ EnableEurekaClient on the startup class. Finally, start the service and access http://localhost:8081/student/,http://localhost:8081/flaskserver , it can be found that the gateway configuration is successful

2. Gateway gateway configuration details

server:
  port: 8081
spring:
  application:
    name: Api
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #Enable automatic forwarding according to the micro service name
          lower-case-service-id: true  #The microservice name is rendered in lowercase


      #  There are three ways to configure the uri in the gateway, including
      #The first method: ws(websocket): uri: ws://localhost:9000
      #The second method: http method: uri: http://localhost:8130/
      #The third method: lb (service name in the registry): URI: LB: / / brilliance consumer
      #Rule: configuration is identified by filter name, equal sign (=), and parameter values separated by commas (,).
      routes:
      - id: student           # Route id: payment_route. There are no fixed rules. It is recommended to match the service name
        uri: lb://STUDENT
        predicates:
        - Path=/**    # Assertion: route with path matching
        - Method=GET,POST
        #When the request header carries the value with the key X-Request-Id and contains numbers, it is forwarded
        #- Header=X-Request-Id, \d+
        #Accept remote resource collection
        #- RemoteAddr=192.168.1.1/24
        #- Cookie=mycookie,mycookievalue
        #Receive a time parameter of the java ZonedDateTime class. After means that the request can match the route correctly after this time. Similarly, there are Before and Between
        #- After=2021-07-31T17:42:47.789-07:00[Asia/Shanghai]
        #- Weight=group1, 2 #Load balancing
        #- Query=token, abc.       # The matching request parameter contains token and its parameter value satisfies the regular expression abc Request for

        #filters:
          # Rewrite / 1 to / product/1
          #- PrefixPath=/product
          # Rewrite / api/123/product/1 to / product/1
          #- StripPrefix=2
eureka:
  client:
    service-url:
      # EurekaServer address. Multiple addresses are separated by ','
      defaultZone: http://localhost:8088/eureka
    #Service registration: whether to register with the server. The default value is true
    register-with-eureka: true
  instance:
    #Composition information of service provider instance
    instance-id: ${spring.application.name}:${server.port}

3. Optimization and improvement

Gateway can also customize the configuration of filtering, authentication, etc

Keywords: Spring Cloud

Added by Balu on Tue, 28 Dec 2021 05:18:14 +0200