SpringCloudAlibabaNacos Discovery--Service Governance

Keywords: Big Data Zookeeper Distribution

3.1 Introduction to Service Governance

Think about a question first

 With the actions in the previous chapter, we can already make calls between micro services.But we take the network address of the service provider

( ip Hardcoded into your code, such as ports, has many problems:
  • Once the service provider address changes, you need to modify the code manually
  • Once multiple service providers are present, load balancing cannot be achieved
  • As micro-services become more and more numerous, it is difficult to maintain call relationships manually
So how can we solve this problem? At this point we need to dynamically implement it through the registry Service Governance .
What is Service Governance
Service governance is the most core and basic module in the micro-service architecture.For implementing individual micro services Automated registration and discovery .
  • Service registration: In the framework of service governance, a registry is built, and each service unit registers with the registry the details of its services.And form a list of services in the registry. The service registry needs to monitor the availability of services in the list in a heartbeat way. If not, it needs to exclude the unavailable services from the list.
  • Service discovery: A service invokes a service consulting service with the service registry and obtains a list of instances of all services to access a specific service instance.

        As you can see from the call diagram above, in addition to micro-services, one component is the Service Registry , which is a very important architecture for microservices A component that plays a major coordinator role in the microservice architecture.The registry generally contains the following functions:
1. Service Discovery:
  • Service registration: Save information about service providers and service callers
  • Service subscription: A service caller subscribes to information from a service provider, and the registry pushes information from the provider to the subscriber
2. Service configuration:
  • Configuring subscriptions: Service providers and service callers subscribe to microservice-related configurations
  • Configuration Download: Actively push configuration to service providers and service callers
3. Service Health Detection
  • Detect the health of service providers and perform service culling if exceptions are found
Common registries
  • Zookeeper
        zookeeper is a distributed service framework that is Apache Hadoop A subproject designed primarily to solve distributed problems Some data management issues often encountered in applications, such as unified naming services, state synchronization services, cluster management, distributed applications Configuration item management, etc.
  • Eureka
        Eureka is Springcloud Netflflix An important component of is to register and discover services.But now (since Eureka 2.0) is closed source
  • Consul
        Consul is based on GO Open source tools for language development, mainly for distributed, service-oriented systems providing service registration, service discovery And configuration management functions. Consul Functions are useful, including: service registration / Discovery, Health Examination, Key/Value Storage, multiple data centers, and distributed consistency assurance. Consul It is only a binary executable, so Installation and deployment are very simple, just download from the official website and execute the corresponding startup script.
  • Nacos
        Nacos is a dynamic service discovery, configuration management, and service management platform that makes it easier to build native cloud applications.It is Spring Cloud Alibaba One of the components responsible for service registration discovery and service configuration nacos=eureka+confifig .

Introduction to 3.2 nacos

        Nacos is dedicated to helping you discover, configure, and manage microservices. Nacos Provides a set of easy-to-use features to help you quickly Implement dynamic service discovery, service configuration, service metadata, and traffic management.
        
        As you can see from the above description, nacos serves as a registry To manage each microservice registered.

3.3 Introduction to Nacos

Next, we'll join in the existing environment nacos And register our two microservices.

3.3.1 Setting up a nacos environment

No. 1 step : install nacos
Download Address : https://github.com/alibaba/nacos/releases
download zip Format installation package and decompress
No. 2 step : start-up nacos
In the linux environment:
# Switch directories
cd nacos/bin
# Command Start
startup.cmd -m standalone
In a windows environment:
Decompression package:

 Double-click startup.cmd to start nacos

 

 

Step 3: Visit nacos

Open browser input http://localhost:8848/nacos To access the service. The default password is nacos/nacos

 

 3.3.2 Register commodity microservices with nacos

Start Modifying Next shop - product Module code, register it with nacos On Services
1 stay pom.xml Add in nacos Dependency on
<!--nacos Client -->
<dependency>
        <groupId> com.alibaba.cloud </groupId>
        <artifactId> spring-cloud-starter-alibaba-nacos-discovery </artifactId>
</dependency>
2 Add on Main Class @EnableDiscoveryClient annotation
@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication
3 stay application.yml Add in nacos Address of the service
spring: 
  cloud: 
    nacos: 
      discovery: 
        server-addr: 127.0.0.1:8848
4 Start the service, Watch nacos Is there a registered commodity microservice in the control panel

 

3.3.3 Register order microservices with nacos

Start Modifying Next shop_order Module code, register it with nacos On Services
1 stay pom.xml Add in nacos Dependency on
<!--nacos Client -->
<dependency>
<groupId> com.alibaba.cloud </groupId>
<artifactId> spring-cloud-starter-alibaba-nacos-discovery </artifactId>
</dependency>
2 Add on Main Class @EnableDiscoveryClient annotation
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication
3 stay application.yml Add in nacos Address of the service
spring: 
  cloud: 
    nacos: 
      discovery: 
        server-addr: 127.0.0.1:8848
4 modify OrderController To implement microservice calls
Provides a class that DiscoveryClient can access basic information about a service.
package com.itheima.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.itheima.entity.Order;
import com.itheima.entity.Product;
import com.itheima.service.OrderService;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private OrderService orderService;

    //Ready to buy one item
    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {

        //Get service address from nacos
        ServiceInstance serviceInstance = discoveryClient.getInstances("service-product").get(0);
        String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();

        //Calling commodity microservices through restTemplate
        Product product = restTemplate.getForObject(
            		"http://" + url +"/product/" + pid, Product.class);

        log.info(">>Commodity Information,Query Results:" + JSON.toJSONString(product));

        Order order = new Order();
        order.setUid(1);
        order.setUsername("Test User");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);

        orderService.save(order);

        return order;
    }
}
DiscoveryClient Is responsible for service registration and discovery, through which we can get all the clothes registered to the registry Business
5 Start the service and observe the order microservices registered in the nacos control panel
 

 

6 Then the call succeeds by accessing the consumer service validation

 

3.4 Implement load balancing for service calls

3.4.1 What is load balancing

Generally speaking, load balancing is to distribute the load (work tasks, access requests) among multiple units of operation (servers, Component) is executed on.
Depending on where load balancing occurs , Generally divided into Service-side load balancing and Client Load Balancing .
Service-side load balancing refers to what happens on one side of the service provider , For example, common nginx load balancing
Client load balancing refers to the instance that has been selected to process the request before it is sent to one side of the service request. Request.

In a microservice invocation relationship, we generally choose client load balancing, that is, when one side of a service invocation decides which provider the service is to be executed by.

3.4.2 Customize Load Balancing

1 adopt idea Start one more shop - product Micro service, set its port to 8082

 

 2 View microservice startup via nacos

 You can also view service details

 3 Modify the shop-order code to achieve load balancing (we use random numbers to achieve load balancing ourselves)

package com.itheima.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.itheima.entity.Order;
import com.itheima.entity.Product;
import com.itheima.service.OrderService;

import java.util.List;
import java.util.Random;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private OrderService orderService;

    //Ready to buy one item
    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {

        // Get service address from nacos
        // Custom Rules Implement Random Selection Service
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");

        int index = new Random().nextInt(instances.size());
        ServiceInstance serviceInstance = instances.get(index);

        String url = serviceInstance.getHost() + ":" + serviceInstance.getPort();
        log.info(">>from nacos The microservice address obtained in is:" + url);

        //Calling commodity microservices through restTemplate
        Product product = restTemplate.getForObject(
                "http://" + url +"/product/" + pid, Product.class);

        log.info(">>Commodity Information,Query Results:" + JSON.toJSONString(product));

        Order order = new Order();
        order.setUid(1);
        order.setUsername("Test User");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);

        orderService.save(order);

        return order;
    }

}
4 Start two service providers and one service consumer, access more consumer tests

 

3.4.3 Load Balancing Based on Ribbon

Ribbon yes Spring Cloud A component that allows us to easily achieve load balancing with one comment
No. 1 Step: In RestTemplate Add on Generation Method @LoadBalanced annotation
@Bean
@LoadBalanced
public RestTemplate restTemplate () {
    return new RestTemplate ();
}
No. 2 Step: Modify the method of service invocation
package com.itheima.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.itheima.entity.Order;
import com.itheima.entity.Product;
import com.itheima.service.OrderService;

import java.util.List;
import java.util.Random;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderService orderService;

    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {

        //Get the service address from nacos by using the microservice name directly
        String url = "service-product";

        //Calling commodity microservices through restTemplate
        Product product = restTemplate.getForObject(
                "http://" + url +"/product/" + pid, Product.class);

        log.info(">>Commodity Information,Query Results:" + JSON.toJSONString(product));

        Order order = new Order();
        order.setUid(1);
        order.setUsername("Test User");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);

        orderService.save(order);

        return order;
    }

}
Ribbon Supported Load Balancing Policies
Ribbon Multiple load balancing strategies are built in , The top-level interface for internal load balancing is com.netflix.loadbalancer.IRule , The specific load policy is shown in the following figure :

 We can adjust Ribbon's load balancing strategy by modifying the configuration as follows

service-product: # Name of the provider invoked 
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3.5 Feign-based implementation of service calls

3.5.1 What is Feign

Feign is Spring Cloud A declarative pseudo supplied Http Client, which makes calling a remote service like calling a local service
service It's as simple as creating an interface and adding a comment.
Nacos is very compatible Feign , Feign Integrated by default Ribbon So in Nacos Use below Fegin Negative by default Load balancing effect.

Use of 3.5.2 Feign

1 join Fegin Dependency on
<!--fegin assembly -->
<dependency>
        <groupId> org.springframework.cloud </groupId>
        <artifactId> spring-cloud-starter-openfeign </artifactId>
</dependency>

2 Add Fegin's comment on the main class

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // open Fegin
public class OrderApplication {}
3 Create a Service under shop-order ProudctService And use Fegin Implement microservice calls
package com.itheima.service;

import com.itheima.entity.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("service-product") //Declare the provider name of the call
public interface ProductService {
    
     // Specify which method to invoke the provider
     // @FeignClient+@GetMapping is a complete request pathhttp://service- Product/product/{pid}
     @GetMapping(value = "/product/{pid}")
     Product findByPid(@PathVariable("pid") Integer pid);
    
}
4 modify controller Code and start validation
package com.itheima.controller;

import com.itheima.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.itheima.entity.Order;
import com.itheima.entity.Product;
import com.itheima.service.OrderService;

import java.util.List;
import java.util.Random;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private ProductService productService;
    
    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {

        //Calling commodity microservices through fegin 
        Product product = productService.findByPid(pid);

        log.info(">>Commodity Information,Query Results:" + JSON.toJSONString(product));

        Order order = new Order();
        order.setUid(1);
        order.setUsername("Test User");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);

        orderService.save(order);

        return order;
    }

}

5 Restart order micro-service to see the effect

 

Posted by sprocket on Tue, 07 Sep 2021 10:31:38 -0700