This is the 11th day of my participation in Gwen Challenge

Ribbon

An overview,

  • Load balancing is to distribute customer requests to other servers to achieve high service availability.
  • Local load balancing and server load balancing
    • The Ribbon is a local load balancer. When invoking the microservice interface, the Ribbon first caches the services from the registry to the local JVM and implements remote RPC calls locally.
    • Nginx is a server load balancer. Users’ requests are handed to Nginx, and then Nginx forwards the requests, and the server implements load balancing.

The Ribbon is a load balancing +ResultTemplate call

2. Load balancing rules

The default is round search, which can be customized.

1. Load Balancing rules in the Ribbon:

  • RoundRobinRule: polling
  • RandomRule: random
  • RetryRule: Polls first and retry at a specified time if the poll fails
  • WeightedResponseTimeRule: The faster the response, the greater the weight and the easier to select.
  • BestAvailableRule: Filters out services that fail multiple times and selects the service with the least concurrency
  • AvailabilityFilteringRule \ ZoneAvoidanceRule: similar to BestAvailableRule

2. Replace load rules

Note: Rule classes for load rule replacement cannot be placed in the scope of the @ComponentScan scan

Rule configuration class

@Configuration
public class MySelfRule {
    // Configure random load rules
    @Bean
    public IRule myRule(a) {
        return newRandomRule(); }}Copy the code

The main boot class is added @ribbonClient

@EnableEurekaClient
@SpringBootApplication
// Load balancing for cloud-payment-service using the rule MySelfRule
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = MySelfRule.class)
public class OrderMain8080 {
    public static void main(String[] args) { SpringApplication.run(OrderMain8080.class, args); }}Copy the code

3. Principle of load balancing round search algorithm

Load balancing algorithm: Number of REST interface requests % Number of server clusters = subscript of actual server location. Each time the rest service is started, the value starts from 1.

Interface LoadBalancer

public interface LoadBalancer {
    ServiceInstance instance(List<ServiceInstance> serviceInstances);
}
Copy the code

implementation

@Component
public class LoadBalancerImpl implements LoadBalancer {
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public ServiceInstance instance(List<ServiceInstance> serviceInstances) {
        // Get the index of the current service
        int index = getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }


    /** * Get the number of service accesses with CAS spin lock **@return* /
    public final int getAndIncrement(a) {
        int current;
        int next;

        do {
            current = this.atomicInteger.get();
            next = current >= Integer.MAX_VALUE ? 0 : current + 1;
        } while (!this.atomicInteger.compareAndSet(current, next));

        returnnext; }}Copy the code

test

@RestController
@RequestMapping("/consumer")
public class OrderController {
    private final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
    @Resource
    private LoadBalancer loadBalancer;
    @Resource
    private DiscoveryClient discoveryClient;
    
    @GetMapping("/getPort")
    public String getPortLB(a) {
        // Find the list of services based on the service name
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if (instances == null || instances.size() <= 0) {
            return null;
        }
        ServiceInstance serviceInstance = loadBalancer.instance(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri + "/payment/getPort", String.class); }}Copy the code

Open Feign

An overview,

Feign is a declarative Web Service client. It makes Web services simpler. Define a Service interface and annotate it. Feign integrates with the Ribbon, and Feign is called in declarative methods with interface bindings. OpenFeign’s @FeignClient can parse the interface under SpringMVC’s @RequestMapping annotation, and generate implementation classes through dynamic proxy, which can perform load balancing and call other services.

Open Feign service invocation

Import dependence

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Copy the code

Start OpenFeign by adding annotations to the startup class

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) { SpringApplication.run(OrderFeignMain80.class, args); }}Copy the code

Create an interface to invoke the service, identify the name of the service that provides the service, and specify the corresponding URL

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
    @GetMapping("/payment/getById/{id}")
    ResultDto<Payment> getPaymentById(@PathVariable("id") Long id);
}
Copy the code

Test call

@RestController
public class OrderFeignController {
    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping("/consumer/get/payment/{id}")
    public ResultDto<Payment> getPaymentById(@PathVariable("id") Long id){
        returnpaymentFeignService.getPaymentById(id); }}Copy the code

Open Feign timeout control

demo

    // Set the service provider to wait 3 seconds
    @GetMapping("/getPort")
    public String getPort(a) {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return port;
    }
Copy the code

The Open Feign client waits by default for one second and throws an error if it does not receive a response from the provider for more than a second. To avoid this, manually set the timeout.

Adding a Configuration file

ribbon:
  # refers to the time taken to establish the connection
  ReadTimeout: 5000
  # means to get resources all the time
  ConnectTimeout: 5000
Copy the code

Open Feign log enhancement

Feign provides the log printing function. You can adjust the log level through configuration and monitor and output the invocation status of Feign interfaces. Log level:

  • NONE: By default, no logs are displayed.
  • BASIC: record request method, URL, response status and response time;
  • HEADERS: Records request and response HEADERS in addition to BASIC.
  • FULL: In addition to the information in HEADERS, the body and metadata of the request and response are recorded

Configure levels using configuration classes

@SpringBootConfiguration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(a){
        returnLogger.Level.FULL; }}Copy the code

Enable logging in the configuration file

logging:
  level:
# feign Logs monitor which interface at which level
    cn.yylm.springcloud.service.PaymentFeignService: debug
Copy the code