“This is the 17th day of my participation in the First Wen Challenge 2022.First challenge in 2022”
SpringCloud microservices distributed
This article is based on the previous code to modify learning click 👍
The basic architecture of Eureka
I learned the basics of Eureka in my last post
- Eureka consists of two components:
Eureka Server
andEureka Client
- Eureka Server registryThe Client ClientProvide:Service registration and service discovery capabilitiesAfter each node Client is started, it is registered in EurekaServer so that the service registry in EurekaServer stores information about all available service nodes.
(The information of the service node can be seen intuitively in the interface)
- EurekaClient is a Java clientTo simplify the interaction with Eureka Server, the client also has a built-in load balancer that uses round-robin load algorithms.After the application starts, it will
On a regular basis
Sends heartbeat to Eureka Server (default interval: 30 seconds).If no heartbeat is received from a node,EurekaServer will remove the service node from the service registry (default: 90 seconds)
Eureka Server ha cluster
Microservers always use data from the local cache when consuming remote apis. Therefore, in general, even if Eureka Server goes down, the calls between services will not be affected.
-
But if EurekaServer goes down, some microservices become unavailable
-
If the cache in Eureka Server is not refreshed, it may affect the invocation of microservices and even the high availability of the entire application system.
-
Therefore, a cluster of highly available Eureka Servers is typically deployed in a build environment.
-
Benefits: Build Eureka clusters and if one of the Eureka registries goes down during application development. Even if, at this point, a Eureka Client changes/stops… Records are also managed by other registries… Make your application highly available
-
Eureka Server can run multiple instances and
Each registered
To implement cluster ha deployment -
Eureka Server instances incrementally synchronize information with each other to ensure consistent data on all nodes.Registering nodes with each other is the default behavior of Eureka Server. (Above: Cluster operations between three registries… Synchronize data between registries and manage provider and ComSumer together
If one hangs, the operation will not be affected.
)
Set up a Eureka Server HA cluster
Copy the eureka-Server registry you wrote earlier
For eureka-server2 to facilitate operation between copy
- Change the name…
- Modify the project name in pom.xml
eureka-server2
- The main Maven project
pom.xml
Add a dependency ~ to
This is not clear enough for anyone who has learned Maven…Maven pom Lord. XML
<! The Maven parent project contains the management child project... -->
<modules>
<module>common_api</module>
<module>common_orderService</module>
<module>common_userService</module>
<module>eureka-server</module>
<module>eureka-server2</module> <! Update Maven to add copy projects to projects... -->
<module>import-demo</module>
</modules>
Copy the code
Ok, so that’s about itRegistration center
Modify port/configuration of registry:
The next step is to configure the registry…. Eureka – server2. Yml
server:
port: 7002 # modified... Port of the registry; (Know that ports are unique...)
spring:
application:
name: eureka-server The registry application name does not need to be changed...
# Configure the registry....
eureka:
client:
service-url: # Registered address leaked from registry... Comma separated, no Spaces!!
defaultZone: http://localhost:7002/eureka/,http://localhost:7001/eureka/
fetch-registry: false
register-with-eureka: false
Copy the code
Eureka – server.yml
server:
port: 7001 # registry port;
spring:
application:
name: eureka-server The registry application name does not need to be changed...
# Configure the registry....
eureka:
client:
service-url: # Registered address leaked from registry...
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
fetch-registry: false
register-with-eureka: false
Copy the code
test
Start the Eureka-Server registry Start common_orderService orders module | common_userService user module Start the Eureka-Server2 registry
Closing the 7001 registry and testing will not affect the use of… Note:
- Because the registry is closed, Eureka’s client will detect it
A registry is down
Out of the ordinary! But will not affect the use!
Ok, Eureka is in effect!
Eureka cluster summary:
-
Create two exception ports
port
F, basically the sameThe registry
-
To its. Two registry interdependence in the configuration of yml: = = defaultZone: http://localhost:7002/eureka/, http://localhost:7001/eureka/==
Eureka source code analysis
Automatic loading in SpringBoot
The ImportSelector interface is the core interface Spring uses to import external configuration
In the automated configuration of SpringBoot and @enablexxx (functional annotations)Decisive role.
First ImportSelector is an interface:
- When in the Class annotated at @Configuration
- After introducing an ImportSelector implementation class using @import
- All Class names returned by methods in the implementation Class are defined as beans.
public interface ImportSelector {
// Implement interface need to override method, return value is an array... Store class name data;
// Use @import in an @Configuration class to introduce the implementation class of the interface;
// All class names are defined as beans...
String[] selectImports(AnnotationMetadata var1);
}
Copy the code
DeferredImportSelector interface and ImportSelector
DeferredImportSelector is a subinterface to ImportSelector… DeferredImportSelector. Java interface
public interface DeferredImportSelector extends ImportSelector {... }Copy the code
To view:
- Go to @SpringBootApplication — go to — @enableAutoConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class}) / / enter AutoConfigurationImportSelector. Class
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude()default {};
String[] excludeName() default {};
}
Copy the code
Enter — AutoConfigurationImportSelector. Class DeferredImportSelector role:
The DeferredImportSelector interface inherits ImportSelector
- The difference between this and the ImportSelector is when the bean is loadedDeferredImportSelector does not load until all @Configuration is executed…
Must be slower than ImportSelector...
Customize one using ImportSelector@Eablexx
Startup notes:
Implementation: @eabelexxx starts class annotations. Only with annotations can you use this class in your program.@Eable cannot use class as method () if not started...
This time add a module import_Eable
Create entity under com.wsm.entity package:
Define the Bean object user.java
public class User {
String name;
String age;
/ / omit get/set/toString...
}
Copy the code
Com.wsm. config config package to start the implementation code:
Define the Configuration class. Configuration Class Userconfig.java
// The @configuration class does not declare a Configuration class, but it already uses @bean for load injection;
public class UserConfig {
@Bean
public User createUser(a) {
User u = new User();
u.setName("Zhang");
u.setAge("12");
returnu; }}// It is not immediately loaded into the Spring container, but the following classes are uniformly loaded by ImportSelector...
Copy the code
Define ImportSelectorUserImportSelector. Java
//UserImportSelector implements the ImportSelector interface, overriding the method...
public class UserImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{UserConfig.class.getName()}; // Return an array of strings containing the names of the classes to be loaded..
}
// The method return value character array [] contains the class to be loaded via @import...
}
Copy the code
Custom create open annotations:EnableUser.Java
@Retention(RetentionPolicy.RUNTIME) // Class execution completes when the class is loaded
@Documented
@Target(ElementType.TYPE)
//------- These are Java annotations
@Import(UserImportSelector.class) // Import the implementation Class with import(UserImportSelector.Class)..
public @interface EnableUser {
// Use @interface to define a custom annotation: @enableuser;
// It is a binding annotation that contains one inside: @import (UserImportSelector. Class)
// using @enableUser is equivalent to using @import (UserImportSelector. Class)!!
}
Copy the code
ok ! . Project Maven release:install
: internal contains clean package deploy test compile… Operation;
Testing:
The Jar package has been prepared and published to Maven’s local repository… So now direct: project references can use annotations… I am using a registry that is not often used otherwise and there is already a User class in the order and User module to avoid conflicts and facilitate testing…
Operation start:
- The pom.xml of the eureka-server2 module is introduced into the import_Eable module
- Refresh Maven to the main program class using the @eableUser annotation
MyEurekaServer2 .Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.ConfigurableApplicationContext;
import wsm.config.EnableUser; // This is just a custom annotation!! This will enable the loading of the User class...
import wsm.entity.User;
@SpringBootApplication // Also know that there is an @SpringBootConfiguration under the @SpringBootApplication annotation
@EnableEurekaServer // Comments main program to start Eureka service
@EnableUser // Import custom annotations to complete the following User
public class MyEurekaServer2 {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MyEurekaServer2.class, args);
User u = (User) run.getBean("uu"); // load into the Spring container according to @bean ("uu"); Via @eableUser!System.out.println(u); }}Copy the code
Eable comment out; error when running!! What a strong note! This is like a class switch that you turn on when you need it and off when you don’t! then@EnableEurekaServer
The autowiring of….(behind separate out a detailed explanation… Chinese New Year more!
Eureka replacement plan Consul
Eureka closed source effect
Eureka 2.x closed source announced on Euraka’s GitHub. This means that developers continue to use code bases and artifacts released as part of an existing working REPO on the 2.x branch at their own risk. Alas, it is a pity that we need to find a new registry
Consul overview
Consul is a popular service discovery tool in recent years. Consul has three main application scenarios: service discovery, service isolation, and service configuration.
- Consul is an open source tool from HashiCorp for service discovery and configuration in distributed systems.
- Consul’s solution is more “one-stop” than other distributed service registration and discovery solutions
- Built-in service registration and discovery frame, distributed consistency protocol implementation, health check, Key/Value storage, multi-data center solution
- No longer need to rely on other tools (such as ZooKeeper, etc.). It is also simpler to use.
- Consul is written in the Go language, making it naturally portable (Linux, Windows, and Mac OS X support);
The installation package contains only one executable file for easy deployment and works seamlessly with lightweight containers such as Docker.
Consul’s advantages:
- Raft algorithm is used to ensure consistency, which is more straightforward than the complex Paxos algorithm. Zookeeper uses Paxos while ETCD uses Raft.
- Supports multiple DCS, and uses different ports for listening on Intranet and extranet services.Multi-dc cluster can avoid single point of failure of a single DC, and its deployment needs to consider network latency and fragmentation.
Zookeeper and ETCD do not support the MDC function. - Supports health check. Etcd does not provide this functionality.
- Supports HTTP and DNS interfaces. Zookeeper integration is complex, and ETCD supports only HTTP.
- The official web management interface etCD does not provide this function.
Consul is a rising star in service registration and configuration management
Consul versus Eureka
- consistency
CAP
Consul Strong Consistency (CP) Eureka guaranteedHigh availability
And final consistency (AP) - Develop language and usageEureka is a servlet application that runs in a servlet container
SpringBoot internally integrates Tomcat..
Consul is written from go and can be installed and startedStart one before use
Start the programconsul.exe
CAP principle is also called CAP theorem
- It refers to consistency in a distributed system
Consistency
, availability,Availability
, partition fault tolerancePartition tolerance
- The CAP principle is that, at best, these three elements can achieve two, not all at once.
- Consistency of CWhether all data backups in a distributed system have the same value at the same time. The registry is represented by:
In a clustered registry environment, a client service sends changes, registers with the registry,
All registries must be synchronized before requests can continue… - Availability of AEnsure that every request has a response regardless of success or failure.
Final consistency
The registry is represented by:In a clustered registry environment, a client service sends changes, registers with the registry,
No, all registries are synchronized to continue operations… It will continue the current operation, silently doing synchronization in the background - Partition tolerance pThe loss or failure of any information in the system does not affect the system operation.
P represents the network communication protocol in the synchronization process...
What is high availability?
- High availability, or HA for short
- A feature or indicator of a system that provides a higher performance than the average normal service time.
Consul download and installation
It says that a client is required to execute the program to start:consul.exe
Under CMD, specify the client execution program directory:
Consul. Exe agent - dev - client = 0.0.0.0
Local boot access:localhost:8500
Request to via GEThttp://127.0.0.1:8500/v1/catalog/services
View the list of all servicesRequest to via GEThttp://127.0.0.1:8500/v1/catalog/service/
Service Name View service details
Basic use of Consul
- Consul supports health checks and provides apis for HTTP and DNS calls to complete service registrations
- Service discovery, and K/V storage of these functions. Get a feel for Consul by sending an HTTP request
Follow-up to learn..
Service registration and discovery
Go to Baidu to find out what it's worth...
Send a PUT request to postmanhttp://127.0.0.1:8500/v1/catalog/register
{“Datacenter”: “dC1 “, “Node”: “node01”, “Address”: “192.168.74.102”, “Service”: {“Datacenter”:” dC1 “, “node01” : “192.168.74.102”, “Service”: {” ID “:” mysql – 01 “, “Service” : “mysql”, “tags” : / “master”, “v1”, “Address” : “192.168.74.102”, “Port” : 3306}
Consul based service registration
Find a microservice module to modify, first of all, this module before the Eureka configuration comment out!! Because we’re using Consul as our registry…
Consul Registry through the applicationBoot directly!!
Modify the poM file associated with the microservice common_orderService order module:
Will eureka depend onpom.xml
And the configuration.yml
Remove, useConsul Registry
Add the Consul based dependencies provided by SpringCloudPom.xml
<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>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0 the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_orderService</artifactId>
<! -- Key!! -->
<dependencies>
<! -- common_orderService project introduced common_API -->
<dependency>
<groupId>org.example</groupId>
<version>1.0 the SNAPSHOT</version>
<artifactId>common_api</artifactId>
</dependency>
<! Eureka-server service dependency -->
<! -- <dependency>-->
<! -- <groupId>org.springframework.cloud</groupId>-->
<! -- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
<! -- </dependency>-->
<! -- Consul based service Registration
<! -- Service discovery based on Consul provided by SpringCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<! -- Use it to check heartbeats -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
Configuring service Registration.yml
server:
port: 6001 # set port 6001 to 6001
spring:
application:
name: order-server # set the name of the micro service, the following registration/call service is based on this;
Configuration of consul;
cloud:
consul: Cloud add: Consul configuration;
host: 127.0. 01. Consul's Server request address
port: 8500 # indicates the port of Consul's Server
discovery: Configure service registration and discovery
register: true
instance-id: ${spring.application.name}-${server.port} ${spring.application. Name}-${server.port} ${spring.application. Name}-${server.
service-name: ${spring.application.name}
port: ${server.port}
ip-address: ${spring.cloud.client.ip-address} Request IP for the current micro service
prefer-ip-address: true To enable IP address registration is to display IP
# Original Eureka registration service configuration...
#eureka:
# client:
# service-url:
# # defaultZone: http://localhost:7001/eureka/, http://localhost:7002/eureka/ specified service registry registry;
# instance:
# prefer-address: true # prefer-address: true # prefer-address: true # prefer-address: true
# instance-id: ${spring.cloud.client. Ip-address}:${server.port} # instance-id: ${spring.cloud.client.
# lease-renewal-interval-in-seconds: 5
# lease-expiration-duration-in-seconds: 10 # If there is no delay in renewing the heartbeat...
Copy the code
Modify theService/Client
Consul Registry
Modify the common_orderService order module main program annotation to myOrderServer.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//import org.springframework.cloud.netflix.eureka.EnableEurekaClient; // Comment the Eureka reference
@SpringBootApplication
// @enableEurekaclient //Eureka special annotations start client registration ~
@EnableDiscoveryClient // General registry notes ~
public class MyOrderServer {
public static void main(String[] args) { SpringApplication.run(MyOrderServer.class, args); }}Copy the code
- Will @ EnableEurekaServer
Eureka special registration annotations
Replacement for @ EnableDiscoveryClientCommon registry annotations
- Start main program: Don’t forget to start Consul client or you’ll get an error! Failed to start ~
- @enableDiscoveryClient This is a universal annotation that can be used by clients and servers, even if your registry is Eureka!
Summary using Consul Registry:
- If it was a microservice from another registry;
Clean up other registry code
- Local boot up well in advance
Consul
The registry - Importing Consul Dependencies
pom.xml
- configured
.yml
file - Use the common Startup Registration Service annotation:
@EnableDiscoveryClient
Refresh the page to see the microservicesRegistered to the Consul
Ribbon The client
Load balancing
Change the above cousul registry to the Eureka registry to illustrate:Eureka integrates Reibbon internally
What is theLoad balancing
- Load balancing
It's a computer technology
- Used to distribute load among multiple computers (clusters of computers), network connections, CPUS, disk drives, or other resources
- To optimize resource usage, maximize throughput, minimize response time, while avoiding overload.
Why do you need load balancing
- In our daily life, we often have to go to some crowded places, such as subway stations, railway stations, cinemas, banks and so on.
- Whether buying tickets or queuing for admission, these places will generally set up multiple service points or entrances. In most cases, the nearest entrance will be crowded if there is no one to guide it. The service points or entrances that are far away are much looser. In this case, there is a huge waste of resources
- Because if these queuing people can be well dispersed to each entrance, it will greatly shorten the queuing time.
- In fact, the construction of the website is the same. In order to improve the service capacity of the website, many websites adopt cluster deployment, like a theater with multiple entrances. At this point, a coordinator is needed to evenly distribute these user requests, so that users can be evenly distributed to different servers.
What is Ribbon?
- The Ribbon is a Netflix load balancer that helps control HTTP and TCP client behavior.
- In SpringCloud, Eureka is used in conjunction with the Ribbon, which provides client load balancing functions. The Ribbon uses the service information it reads from Eureka.
- When a service node is called to provide a service, the load is reasonable.
Load balancer on the client side, not the server side.
The main functions of the Ribbon
- Service invocation gives the Ribbon a service name-request path mapping of all the services that pull through the channel when a service invocation is implemented. The final call is made with the RestTemplate
- Load balancing When there are multiple service providers, the Ribbon automatically selects the service address to invoke based on the load-balancing algorithm
build
Because Eureka is integrated with the Ribbon, there is no additional dependency loading.
When creating the RestTemplate, declare @loadBalanced
- Invoke remote microservices with restTemplate:
There is no need to concatenate the URL of the microservice
, waiting for the requested service name to replace IP address!!
Copy an order module directly to common_orderService2
The provider provides two identical order modules to doLoad balancing ~
- Modify the pom.xml project name
- The parent pom.xml is introduced to connect Maven ~
Same as the above two registries
Changing the port Number
Although the service functions are the same, the port is uniquecommon_orderService1 6001 common_orderService2 60036002 is used by user module...
Distinguish between two order modules ~
Ok, after two almost identical order modules are finished (module name and port are different)… Common_orderService OrderService.java = common_orderService orderService.java = common_orderService orderService.java
@Service
public class OrderService {
// Simulate fake order set...
private static List<Order> orders = new ArrayList<>();
// Class load gets some data by default.. Simulated fake orders..
static {
orders.add(new Order(1."The order 11".10.0.1));
orders.add(new Order(2."Order 21".10.0.2));
orders.add(new Order(3."Order 31".10.0.1));
orders.add(new Order(4.41 "order".10.0.2));
}
/ / get the host IP post -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - load balance ~
// @value (" ${} can be used to obtain the Value in the properties file.. And assign to the object ~")
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String post;
// Get the order set according to the input user ID..
public List<Order> findOrderByUser(Integer uid) {
/ / in order to distinguish between load balancing IP call to print and post -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - load balance ~
System.out.println(ip+":"+post);
List<Order> myorders = new ArrayList<>();
// Go through the collection to get uid consistent data stored in the collection returns...
for (Order order : orders) {
if(order.getUid() == uid) { myorders.add(order); }}returnmyorders; }}Copy the code
Launch the registry and two order microservice modules respectively
Change how the caller calls the Consumer…
Modify the caller user moduleRestTemplate
Load balancing is configured on the caller
Add @loadBalanced MyUserServer.java to an instance of the RestTemplate class
@SpringBootApplication
@EnableEurekaClient
public class MyUserServer {
public static void main(String[] args) {
SpringApplication.run(MyUserServer.class, args);
}
@LoadBalanced // Add the @loadBalanced annotation to the RestTemplate class and call services from the RestTemplate using ------ load balancing by default!
@Bean
// Instantiate RestTemplate to facilitate Service
// Don't forget the @SpringBootApplication composite annotation can have @SpringBootConfiguration, which is also a Spring configuration class!
public RestTemplate createRestTemplate(a) {
return newRestTemplate(); }}Copy the code
To change theRestTemplate
Call method of
Userservice.java ** Lines 17 to 18 load balancing calls ~**
@Service
@Slf4j // Load lo4g using...
public class UserService {
@Autowired
private RestTemplate restTemplate;
// Network communication via restTemplate returns.. Data from other remote modules (although now all local but emulated)
@Autowired // Implement dynamic call...
private DiscoveryClient discoveryClient;
public List<Order> currentUserOrder(Integer uid) {
// Get the microserver module instance on the registry according to the service name;
// Return a collection: it is possible that the service exists on multiple registries, 'load balancing ~' is therefore a collection;
List<ServiceInstance> instances = discoveryClient.getInstances("order-server");
ServiceInstance serviceInstance = instances.get(0); // This time there is only one...
log.info("User service invokes order service");
/ / ribbon load balancing call -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// Because you now have two identical order-server microservices, but also use IP + port is fixed, through load balancing to complete the dynamic call ~ so directly use the module service name to express microservices!
String myurl = "http://order-server/findOrderByUser/" + uid;
// The service controller requests its parameter uid
//String myurl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/findOrderByUser/" + uid;
log.info(myurl);
List<Order> list = restTemplate.getForObject(myurl, List.class);
returnlist; }}Copy the code
test
Continuously refresh the user module to see the result of the order module being called…Distribution is called three times
The default load balancing mode is:Round robin load balancer.. And take turns running one by one...
Conclusion:
- Load balancing is configured in the Consumer caller to implement load balancing calls to modules with the same service name
- Add the @loadBalanced annotation to the RestTemplate object of the caller to make the load-balancing call ~
- Modify the Service layer, the call method is adopted
http://service name/request name /{parameters}/{parameters.. }
formLoad balancing call;
Modify load balancing configurations
Of load balance of related configuration, the default prefix used polling: com.net flix. Loadbalancer.
- BestAvailableRule Selects a server with the smallest concurrent request
- AvailabilityFilteringRule filter out those because connection is marked as circuit tripped backend server, and filter out the high concurrency backend server (active connections over configuration threshold value)
- WeightedResponseTimeRule assigns a weight based on response time, and the longer the response time, the smaller the weight and the less likely it is to be selected.
- RetryRule Retry mechanism for the selected load balancing policy.
- RoundRobinRule roundRobin select server (default)
- RandomRule Selects a server at random
- ZoneAvoidanceRule compound determines the performance of the zone where the Server is located and selects the Server for availability of the Server
.yml
How to configure load balancing calls under the caller module:Then configure the load balancing configuration of the order module under the user module
order-server: # order-server is the name of my service... Current my order module ~
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # Modify load balancing policy random method service
Copy the code
Because it is the name of the service, there is no code warning:Copy between suggestions
Support retry microserver
When one of the load balancing modules goes down, the Ribbon detects it and tries to restart the service. Will not retry ~
Again, this is serving,The caller
The User User module declared by the module
Introduction of depend onpom.xml
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
Copy the code
The configuration of yml
.yml
order-server:
ribbon:
ConnectTimeout: 250 Connection timeout
ReadTimeout: 1000 Data read timeout
OkToRetryOnAllOperations: true Whether to retry all operations
MaxAutoRetries: 1 Number of retries for the current instance
MaxAutoRetriesNextServer: 1 Number of retries for switching instances
Copy the code
Feign service invocation
So far we have seen three microservice invocation methods for SpringBoot: Consumer — call — Provide:
- RestTemplate hardcoded formal service invocation
- DiscoveryClient implements dynamic calls…List the instances = discoveryClient. GetInstances (” module service name “);
Returns a collection of modules based on the module service name
ServiceInstance serviceInstance = instances.get(0);Get a module;
String myURL = “http://serviceinstance.gethost () + “:” + serviceinstance.getPort () + “/ request name /” + parameter ~; serviceInstance.getHost()The service of the host
serviceInstance.getPort()Service port number
. - The RestTemplate declared by the @loadBalanced annotation makes service calls in the form of load balancing
String myURL = "http://multiple providers provide module/request name /"
According to different work requirements, use different service invocation modes…. Here’s how Fegin does it
Introduction of Feign
Interface oriented development ~
Feign is a statement developed by NetflflixTemplated HTTP client
- Inspired by Retrofifit,JAXRS-2.0, and Websocket.feign, it helps us make easy and elegant calls to HTTP apis
- Feign supports a variety of annotations, such as Feign’s own annotations or JAX-RS annotations.
- Feign has been enhanced by SpringCloudMade Feign support for SpringMVC annotations and integration
Ribbon
andEureka
To make Feign easier to use. - In SpringCloud, using Feign is as simple as creating an interfaceAdd some annotations to the interface, and the code is done;
In Eureka, a Consumer can also invoke the Provider's interface as a method invocation
Very easy and very fast. Can effectively reduce the amount of code.
Build start
Create a user fegin module: common_userService_fegin
Implementation of fegin call method, callOrder module (provide)
addfegin
Dependent component: POM.xml
pom.xml
<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>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0 the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_userService_fegin</artifactId>
<dependencies>
<! Maven subproject API entity -->
<dependency>
<artifactId>common-api</artifactId>
<groupId>com.zb</groupId>
<version>1.0 the SNAPSHOT</version>
</dependency>
<! -- Eureka dependent ~ -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<! -- Fegin depends!! -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
Copy the code
addfegin
The mot configuration
Port service name Eureka Configuration center Management… In order to prevent errors on the copy, there are already a lot of duplicate things…. application.yml
server:
port: 6004 Change port 6004
spring:
application:
name: User - server - fegin # set the name of the micro service, the following registration/call service is based on this;
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port} # display IP number on Eureka..
Copy the code
- The default Tomcat port for SpringBoot is 8080
- Because ports are unique, SpringCloud is also a microservice architecture, one per service, which requires frequent port changes
If a service doesn't work. Check the port problem first ~
Create the main program class:
Enable Spring Cloud Feign support with the @enableFeignClients annotation myUserFeginServer.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients // Start classes to add Feign support
public class MyUserFeginServer {
public static void main(String[] args) { SpringApplication.run(MyUserFeginServer.class, args); }}Copy the code
Com.wsm. client interface package:
Based on interface oriented programming…
Create an interface that is the core interface for invoking microservices in Feign
- Declaration on interface
@feignClient (" Specify the microservice provider service name to invoke ")
- The class then declares the same method to be invoked in the provider service, including parameters.
Fegin automatically makes the underlying matching mapping call ~
OrderFeginClient.Java
import com.zb.entity.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
// @feignClient specifies the name of the microservice to call
@FeignClient("order-server")
public interface OrderFeginClient {
// Call the request path, note that this should be as close as possible to the implementation method of the provider, including parameters, parameter types!!
@GetMapping("/findOrderByUser/{uid}")
public List<Order> findOrderByUser(@PathVariable("uid") Integer uid);
}
Copy the code
After that, the normal implementation of service and Controller…
UserService.Java
import com.wsm.client.OrderFeginClient;
import com.zb.entity.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private OrderFeginClient ofc; // Get the interface object. @feginclient will automatically inject the class into Spring
public List<Order> currentUserOrder(Integer uid){
return ofc.findOrderByUser(uid); // Call the interface's methods,fegin's bottom layer will call by default, for the service's methods...}}Copy the code
Usercontroller.java will not be explained in detail…
@RestController
public class UserController {
@Autowired
private UserService us;
@GetMapping("/showUserOrder")
public List<Order> showUserOrder(Integer uid){
returnus.currentUserOrder(uid); }}Copy the code
Testing:
Ok, implement the call!
Fegin Service Invocation summary:
- Import depends on POM.xml
- Fegin’s.YML doesn’t have any required configuration…
- When creating the main program class, add
@EnableFeignClients
Start classes to add Feign support - Fegin is interface oriented programming:Create an interface class:
Class declaration @feignClient (" specify provider module name ")
And:Interface methods, note ⚠️ : be consistent with the Provider's controller!!
annotations parameter Parameter type!
Feign Load balancing
Feign already has Ribbon dependencies and auto-configuration integrated into Feign itself
- So we don’t need to import additional dependencies or register the RestTemplate object. Automatic load balancing ~
- This is really cool. It’s automatic
Load balancing ~
Default theory follows ~ - In addition, we can configure the Ribbon directly by using Ribbon. Xx to enable global configuration. You can also configure the specified service using the service name.ribbon. Xx
Feign’s.yml setting
For slow computers, Fegin calls 2 seconds by default. If time out, the request will not be executed… To solve this problem prolong the request response time:
Yml The default timeout period is 10 seconds
feign:
httpclient:
connection-timeout: 10000
client:
config:
default: # feignClients specifies a global timeout for all clients
connectTimeout: 10000
readTimeout: 10000
loggerLevel: basic
Copy the code
For Fegin interfaces, @FeignClient(” specify the provider module name “) is required to specify the calling module if the same @Feginclient (” multiple interfaces declare the same module name “) module is used on multiple interfaces. An error:
.yml requires that the spring.main. allow-bean-meant-overriding property be set to true
spring:
main:
allow-bean-definition-overriding: true
Copy the code
Can avoid this problem!!