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.


Related articles: