Service governance
Help solve the problem that service consumers keep normal communication for services that are constantly online and offline
Service governance isolates service consumers from service providers through abstraction. Consumers don't need to know the real physical address of a specific service provider to be able to call, and they don't need to know how many service providers are available; service providers only need to register themselves in the service governance server to provide services to the outside world, and they don't need to know which services call themselves. On the other hand, service governance can improve application flexibility for microservice architecture. When one of the service provider instances is unavailable or there is a problem, the service governance server can find the problematic service instance and bypass the problematic service instance when scheduling service consumers, so as to minimize the impact on the application
Eureka
- Service governance server (Eureka server, registration center): service registration center, which is responsible for the registration, maintenance, query and other functions of service list, that is, Eureka server.
- Service registration agent (service provider): if a microservice is a service provider, the service configuration information can be registered to the governance server through the service registration agent. The service registration agent can be understood as an Eureka client, which is responsible for registering, renewing and logging off the services provided by the micro service to Eureka server, so that service consumers can discover and consume. When registering the service, you need to provide the service governance server with the service name, host server IP address, service port number, domain name and other main data.
- Service discovery client (service consumer): also an Eureka client. When it starts, it will get all the service registry information from the service governance server by default, and consume the corresponding service through the obtained service registration list information.
Start the application class and add the corresponding annotation
@Enable Eureka server: build a service governance server
@Enable discovery client: indicates that this is an Eureka client. With this annotation, after the Spring Boot is started, it will try to connect with the service governance server according to the information in the configuration. After the connection is successful, service registration or the same step of service registration information will be performed. (consumer production)
Service governance server (service registry) profile:
spring.application.name=servicediscovery #Port number. If it is not set, it is the default port 8080 of boot server.port=8260 #Corresponding configuration of eureka eureka.instance.hostname=localhost eureka.server.wait-time-in-ms-when-sync-empty=5 #Whether the startup service registers the service to the service governance server is false (production) because it is the service governance server itself eureka.client.register-with-eureka=false eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka #Indicates that the registered service registration list data does not need to be synchronized from the service governance server to the local (consumption) after the application is started eureka.client.fetch-registry=false
Service provider profile:
server.port=2100 #service name spring.application.name=userservice eureka.instance.prefer-ip-address=true eureka.client.register-with-eureka=true eureka.client.fetch-registry=true #server address eureka.client.service-url.defaultZone=http://localhost:8260/eureka
Note: Eureka server also provides an endpoint (/ eureka/apps[APPID]) to view the registered service details. We access the endpoint by using Postman. APPID is the service name defined in the configuration file spring.application.name)
How can I find the service after a long time?
package com.cd826dong.clouddemo.product.api; import com.cd826dong.clouddemo.product.entity.ProductComment; import com.cd826dong.clouddemo.product.repository.ProductRepository; import com.cd826dong.clouddemo.product.entity.Product; import com.cd826dong.clouddemo.product.repository.ProductCommentRepository; import com.cd826dong.clouddemo.product.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** * Endpoint of product management * * @author CD826 * @since 1.0.0 */ @RestController @RequestMapping("/products") public class ProductEndpoint { @Autowired private ProductRepository productRepository; @Autowired private ProductCommentRepository productCommentRepository; @Autowired @Qualifier(value = "restTemplate") private RestTemplate restTemplate; /** * Get product information list * @return */ @RequestMapping(method = RequestMethod.GET) public List<Product> list() { return this.productRepository.findAll(); } @RequestMapping(value = "/{id}", method = RequestMethod.GET) public Product detail(@PathVariable Long id){ return this.productRepository.findOne(id); } @RequestMapping(value = "/{id}/comments", method = RequestMethod.GET) public List<ProductCommentDto> comments(@PathVariable Long id){ List<ProductComment> commentList = this.productCommentRepository.findByProductIdOrderByCreated(id); if (null == commentList || commentList.isEmpty()) return Collections.emptyList(); return commentList.stream().map((comment) -> { ProductCommentDto dto = new ProductCommentDto(comment); dto.setProduct(this.productRepository.findOne(comment.getProductId())); dto.setAuthor(this.loadUser(comment.getAuthorId())); return dto; }).collect(Collectors.toList()); } /** * Load the user information of comment author through RestTemplate * @param userId User Id * @return */ protected UserDto loadUser(Long userId) { return this.restTemplate.getForEntity("http://localhost:8280/userservice/users/{id}", UserDto.class, userId).getBody(); } }
Use the restTemplate.getForEntity () method to go to the service registry to find the service. Use the service name defined in the configuration file (userservice is the service we need to call, and the service can create a new boot item to define it),
It achieves the autonomy principle mentioned before microservice; however, when using RestTemplate, it needs to be created on the application boot class application
/** * Service consumers */ @EnableDiscoveryClient @SpringBootApplication public class Application { @Bean(value = "restTemplate") RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
In this way, the basic principle of microservice implementation is completed