How does SpringCloud use Eureka to transfer data between services
- 2021-09-11 20:34:26
- OfStack
I believe that everyone is most concerned about not a lot of broken theories, but also seems to understand them. What they are most concerned about is the parameter transfer and data acquisition between services.
Ok, today, I will tell you how to transmit data between three microservices, namely:
1. The most basic use of Ip port to request access interface to achieve data transmission
2. Using Eureka instead of Ip (hard coding) to realize data transmission
3. Use Feign to realize the data transmission between micro-services in a faster "sub-service" way (don't understand Feign1 for the time being, that is, the first part of SpringCloud will be explained in detail later, and the explanation here is only for yourself under mark1)
Premise: Build the Eureka registration center. Suppose there is one order micro-service (service consumer) and one user micro-service (service provider), and then the order micro-service is needed to call the user micro-service to obtain the user's information, and both services can run normally. In order to facilitate the use of SpringJpa to obtain data here.
1. Use RestTemplate+Ip:
1. Most of the data is transmitted in the form of collections and objects, so here we use the way of collections and objects as an example
Write the called query method in the user micro-service (service provider)
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserRepository userRepository;
@GetMapping("/getallUser")
public List<User> getUserPage(){
return userRepository.findAll();
}
@GetMapping("/getUser")
public User getUser(Long userId){
return userRepository.getOne(userId);
}
}
@Repository
public interface UserRepository extends JpaRepository<User,Long> {
}
@Entity
@Table(name="TM_USER")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
public class User implements Serializable, Cloneable {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long userId;
/**
* Login name
*/
@Column(name = "USER_NAME")
private String userName;
/**
* User name
*/
@Column
private String name;
/**
* Salary
*/
@Column
private BigDecimal balance;
/**
* Age get set Method has been omitted Add by yourself
*/
@Column
private int age;}
Ok, the service provider has written it, so let's start writing the service consumer
2. Add Bean that generates RestTemplate to the startup class of order microservice (service consumer)
@SpringBootApplication
@EnableEurekaClient // Enable eureka Client
public class MicroserviceSimplecConsumerOrderServerApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(MicroserviceSimplecConsumerOrderServerApplication.class, args);
}
}
Added in order microservice (service consumer) profile yml, where localhost: 9021 is changed to user microservice (service provider's Ip and port)
user:
urlPath: http://localhost:9021
Written by the order service control layer, User here is the replication of user microservice, and then the annotations such as @ Column and @ Table are removed, which is only a temporary storage object without any association with the database
@RestController
@RequestMapping("/order")
public class OrderServerController {
@Autowired
private RestTemplate restTemplate;
@Value("${user.urlPath}")
private String urlPath;
// Get the collection mode
@GetMapping("/allUser")
private List<User> getAllUser(){
ResponseEntity<List<User>> responseEntity = restTemplate.exchange("urlPath"+/user/getallUser?",
HttpMethod.GET, null, new ParameterizedTypeReference<List<User>>() {});
return responseEntity.getBody();
}
// How to get a single object
@GetMapping("/getUser")
private User getUser(Long userId){
User user = restTemplate.getForObject("urlPath"+/user/getUser?userId="+userId,User.class);
return user;
}
}
2. Use Eureka to get
It is very simple to directly replace userPath in order microservice (service consumer) OrderServerController with the service name on registered Eureka. Assume that the service name of the user microservice is: microservice-privider-user
spring:
application:
name: microservice-privider-user
Then you can directly perform the replacement process, that is:
@GetMapping("/allUser") // Returns a collection
private List<User> getAllUser(){
ResponseEntity<List<User>> responseEntity = restTemplate.exchange("microservice-privider-user"+"/user/getallUser", HttpMethod.GET, null, new ParameterizedTypeReference<List<User>>() {});
return responseEntity.getBody();
}
// Return object
@GetMapping("/getUser")
private User getUser(Long userId){
User user = restTemplate.getForObject("microservice-privider-user"+/user/getUser?userId="+userId,User.class);
return user;
}
Ok, written using Mode 2
The fixed ip is replaced by the service name, which solves the problem that Ip hard code is not easy to maintain
The third mode of Feign will be explained in detail later in "Feign: Declarative Rest Client."
gitHub Address: https://github.com/mackjie/microservice-spring-cloud Because RabbitMQ is configured, please read ReadMe first and then start the project, otherwise an error will be reported
Eureka Client Construction and Inter-service Call of springcloud Learning
Eureka Client build:
1. Introducing pom dependencies
<!-- Eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. It is recommended to add @ EnableEurekaClient annotation to the startup class
That is, if the selected registry is eureka, @ EnableEurekaClient is recommended.
For other registries (zookeeper, consul, etc.), @ EnableDiscoveryClient is recommended.
3. Configuration file addition:
#eureka
spring.application.name=producer
# Registry address
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
# Do you register yourself
eureka.client.register-with-eureka=true
# Whether to search for service information
eureka.client.fetch-registry=true
# Use ip Address registration
eureka.instance.prefer-ip-address=true
# The status of the registry list display
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
Service invocation:
There are two ways:
1. ribbon (Load Balancing) + restTemplate
Start class addition:
@Repository
public interface UserRepository extends JpaRepository<User,Long> {
}
0
RandomRule stands for random policy
RoundRobinRule for polling policy (default)
WeightedResponseTimeRule denotes a weighting policy
BestAvailableRule represents the least number of requests policy
Then use restTemplate. getForObject () call after automatically assembling RestTemplate in controller.
2. feign (Recommended)
1. Introducing pom dependency
@Repository
public interface UserRepository extends JpaRepository<User,Long> {
}
1
2. Add @ EnableFeignClients annotation to the startup class
3. Create an interface,
@Repository
public interface UserRepository extends JpaRepository<User,Long> {
}
2
Method of rollback:
package com.sumengnan.test.web;
/**
* eureka Fuse callback class
*/
public class HtystrixEurekaFallback implements EurekaServiceApi {
@Override
public String test() {
return " Connection failed, please try again later! ";
}
}
4. Then call eurekaServiceApi. test () after automatically assembling EurekaServiceApi in controller.