in the previous article, I talked about the registration and registration of services. In the microservice architecture, the discovery department is serviced independently, and the communication between services and services is based on http restful. Spring cloud has business service invocation methods, one is ribbon+template, the other is ribbon+rest.
1. Introduction to ribbon
Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.
Ribbon is a load balancing client that can well control some behaviors of http and tcp. Feign integrates ribbon by default.
ribbon already implements these configuration beans by default :
IClientConfig ribbonClientConfig: DefaultClientConfigImpl
IRule ribbonRule: ZoneAvoidanceRule
IPing ribbonPing: NoOpPing
ServerList ribbonServerList: ConfigurationBasedServerList
ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
2.Preparations
This article is based on the project of the previous article, start the eureka-server project; start the service-hi project, its port is 8762; change the port of the service-hi configuration file to 8763, and start it, then you will Discovery: service-hi has registered 2 instances in eureka-server, which is equivalent to a small cluster.
3. Build a service consumer
Create a new spring-boot project and name it: service-ribbon;
In its pom.xml it inherits the parent pom file and introduces the following dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.forezp</groupId>
<artifactId>service-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-ribbon</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.forezp</groupId>
<artifactId>sc-f-chapter2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
</project>
In the configuration file of the project, the registry address of the specified service is http://localhost:8761/eureka/, the program name is service-ribbon, and the program port is 8764. The configuration file application.yml is as follows:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: service-ribbon
In the startup class of the project, register with the service center through @EnableDiscoveryClient; and inject a bean: restTemplate into the ioc of the program; and use the @LoadBalanced annotation to indicate that this restRemplate enables load balancing.
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run( ServiceRibbonApplication.class, args );
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
Write a test class HelloService, and consume the “/hi” interface of the service-hi service through the restTemplate injected into the ioc container. Here we directly replace the specific url address with the program name. In the ribbon, it will be based on the service name. Select a specific service instance, and replace the service name with the specific url when requesting according to the service instance. The code is as follows:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
}
Write a controller and use the method of calling HelloService in the controller. The code is as follows
@RestController
public class HelloControler {
@Autowired
HelloService helloService;
@GetMapping(value = "/hi")
public String hi(@RequestParam String name) {
return helloService.hiService( name );
}
}
Visit http://localhost:8764/hi?name=forezp multiple times on the browser, and the browser alternately displays:
hi forezp,i am from port:8762
hi forezp,i am from port:8763
This shows that when we call the restTemplate.getForObject(“http://SERVICE-HI/hi?name=”+name,String.class) method, we have done load balancing and accessed service instances on different ports.
4. the structure at this moment
A service registry, eureka server, port 8761
The service-hi project ran two instances with ports 8762 and 8763, which were registered with the service registry respectively.
The sercvice-ribbon port is 8764, registered with the service registry
When sercvice-ribbon calls the hi interface of service-hi through restTemplate, because of load balancing with ribbon, it will call the hi interface of service-hi: 8762 and 8763 ports in turn;
Top comments (0)