Table of contents
1.2 Custom implementation of load balancing
1.4 Load balancing based on ribbon
2. Declarative service calls Feign
2.3 Feign Getting Started Program
2.4 Overview of feign principle
2.5 Three methods of feign interface parameter passing
2.6 OpenFeign performance optimization
1. Ribbon load balancing
1.1 What is load balancing
In layman's terms, load balancing is to distribute the load (work tasks, access requests) to multiple operating units (servers, components) for execution.
1.2 Custom implementation of load balancing
1.2.1 Create two service providers provider
1.2.2 The configuration file application.yml sets different port numbers
#ribbon_provider_1
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.57.132 #nacos服务的地址
application:
name: ribbon-provider #向注册中心注册的名字
#ribbon_provider_2
server:
port: 9091
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.57.132 #nacos服务的地址
application:
name: ribbon-provider #向注册中心注册的名字
1.2.3 Create a service consumer consumer
1.2.4 configuration file application.yml
server:
port: 80
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.57.132 #nacos服务的地址
application:
name: ribbon-consumer #向注册中心注册的名字
1.2.5 controller
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
//发送Rest请求的工具类
@Autowired
private RestTemplate restTemplate;
//发现服务的工具类
@Autowired
private DiscoveryClient discoveryClient;
private int index;
@RequestMapping("/getService/{id}")
public User getServic(@PathVariable Integer id){
//获取所有服务
List<String> serviceList = discoveryClient.getServices();
//随机方式获得服务
//int currentIndex = new Random().nextInt(serviceList.size());
//轮询方式获得服务
index=index + 1;
int currentIndex = (index) % serviceList.size();
ServiceInstance serviceInstance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
String url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
//RestTemplate工具类
@Configuration
public class ConfigBean {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
1.2.6 Test: Call the service provider using polling and random strategies respectively
1.3 Ribbon Introduction
1.3.1 What is Ribbon
Spring Cloud Ribbon is a set of client load balancing tools based on Netflix Ribbon.
We don't need to introduce ribbon dependencies, because ribbon dependencies have been integrated in nacos
Ribbon provides many load balancing algorithms by default, such as round robin, random and so on.
1.3.2 Load Balancing Strategy
Load balancing interface:com.netflix.loadbalancer.IRule
1.3.2 Random strategy
Ribbon has 7 built-in load balancing strategies by default:
1、RoundRobinRule
Polling strategy , the strategy adopted by Rabbon by default , if no available provider (provider) is found after one round of polling, it will poll up to 10 rounds, if finally
If not found, NULL is returned.
Example: There are currently 3 providers A, B, and C, first poll one by one, A, B, and C do not visit (1 round), visit A, B, and C once (2 rounds), try in total 10 rounds
Returns NULL if not yet accessible.
2、RandomRule
Random strategy, choose one from all available providers.
3、RetryRule
Retry strategy, first obtain the provider (strategist) according to the RoundRobinRule strategy to get a direct return, if the acquisition fails, retry within the specified time limit,
The default timeout is 500 milliseconds. [RoundRobinRule polling strategy, the default is 10 rounds, and RetryRule I will give you 500 milliseconds, you can keep retrying until you find it]
4、BestAvailableRule
most available strategy. Choose the provider (provider) with the least amount of concurrency, that is, the provider with the least number of connected consumers.
5、AvailabilityFilteringRule
Available filtering algorithms. The algorithm rules are: filter out providers in the fuse state and providers that have exceeded the connection limit, and use a polling strategy for the remaining providers.
6、ZoneAvoidanceRule
zone avoidance strategy. Select the provider according to the zone where the provider is located and the availability of the provider.
7、WeightedResponseTimeRule
"Weight Response Time" policy. The weight of each provider is calculated according to the average response time. The faster the response time, the greater the weight, and the higher the probability of being selected.
A round-robin strategy is used at startup. It will be selected according to the weight later.
1.4 Load balancing based on ribbon
1.4.1 ConfigBean
@Configuration
public class ConfigBean {
@Bean
/**
* 添加了@LoadBalanced注解之后,Ribbon会给restTemplate请求添加一个拦截器,在拦截器中获取
* 注册中心的服务列表,并使用Ribbon内置的负载均衡算法从服务列表里选中一个服务,通过获取到的服务信息 * (ip,port)替换 serviceId 实现负载请求。
*/
@LoadBalanced //开启负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
//随机策略
@Bean
public IRule iRule() {
return new RandomRule();
}
}
1.4.2 Controller
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
//发送Rest请求的工具类
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/get/{id}")
public User getUser(@PathVariable Integer id){
//ribbon-provider为服务要访问的名字即可,Ribbon会把服务名替换成ip和端口号
String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url,User.class);
}
}
1.4.3 Testing
Invoke service providers using polling and random strategies respectively
1.5 Ribbon problems
① It is troublesome to splice url and parameters
②Dead services cannot be removed by default (if one of the services is down, the browser will fail to access)
2. Declarative service calls Feign
2.1 Background
When we call the API of other services through RestTemplate, the required parameters must be spliced in the URL of the request. If there are few parameters, maybe we can bear it. Once there are multiple parameters, then splicing the request string will be more efficient. Low and looking so silly .
So is there a better solution? The answer is yes, Netflix has provided us with a framework: Feign.
2.2 Overview of Feign
Feign is a declarative, templated HTTP client provided by Spring Cloud. It makes calling remote services as easy as calling local services. You only need to create an interface and add an annotation.
Spring Cloud integrates Feign and enhances it, so that Feign supports Spring MVC annotations; Feign integrates Ribbon by default, so Fegin achieves the effect of load balancing by default.
2.3 Feign Getting Started Program
2.3.1 Create a service provider
application.yml
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.57.132:8848 #nacos服务的地址
application:
name: feign-provider #向注册中心注册的名字
Create controller and service
//controller
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired
private UserService userService;
@RequestMapping("/getUserById")
public User getUserById(@RequestParam("id") Integer id){
return userService.getUserById(id);
}
}
//servic接口
public interface UserService {
User getUserById(Integer id);
}
//UserService 实现类
@Service
public class UserServiceImpl implements UserService {
@Override
public User getUserById(Integer id) {
return new User(id,"彭于晏-1",23);
}
}
2.3.2 Create feign interface
pom.xml dependencies
<dependencies>
<!--Spring Cloud OpenFeign Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
create interface
@FeignClient(value = "feign-provider")//value属性写服务名字
@RequestMapping("/provider")//对应提供者的requestmapping
public interface UserFeign {
@RequestMapping("/getUserById")
User getUserById(@RequestParam("id") Integer id);
}
2.3.3 Create a consumer
<dependencies>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入feign接口-->
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>feign_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
Add the @EnableFeignClients annotation to the launcher to scan the feign interface
Call the feign interface in the controller
test
2.4 Overview of feign principle
1. Scan the proxy class of the feign interface into the Spring container :
@EnableFeignClients enables feign annotation scanning: FeignClientsRegistrar.registerFeignClients() scans the interface marked by @FeignClient to generate a proxy class,
and hands the interface and proxy class to Spring’s container management.
2. Create a RequestTemplate
for the method of the interface . When the consumer calls the feign proxy class, the proxy class will call SynchronousMethodHandler.invoke() to create a RequestTemplate (url, parameter)
3. Sending a request
proxy class will create a Request through the RequestTemplate , and then the client (URLConnetct, HttpClient , OkHttp) use Request to send the request
2.5 Three methods of feign interface parameter passing
1. Path splicing? To pass parameters, add the @RequestParam ("id") annotation before the parameters :
2. For restful parameter passing, add the @PathVariable("id") annotation before the parameter:
3. For pojo, add the @RequestBody annotation before the parameters:
2.6 OpenFeign performance optimization
1. Log enhancement
OpenFeign
Although the log enhancement function is provided, no logs are displayed by default, but developers can configure the log level by themselves during the debugging phase.
OpenFeign
The log levels are as follows:
- NONE : default, do not display any logs;
- BASIC : Only record the request method, URL, response status code and execution time;
- HEADERS : In addition to the information defined in BASIC, there are request and response header information;
- FULL : In addition to the information defined in HEADERS, there are request and response body and metadata.
1.1. The configuration file application.yml is set to enable the log:
#com.bjpowernode.feign包下接口的日志级别
logging:
level:
com.bjpowernode.feign: debug
#OpenFeign 的日志级别
feign:
client:
config:
default:#此处写服务名字或default默认的
loggerLevel: full
The log effect printed by the console
1.2. Configure the OpenFeign log level in the configuration class
Customize a configuration class and set the log level in it, which is a global configuration
@Configuration
public class FeignConfiguration {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
Local configuration, specify this configuration in the client interface
configuration = FeignConfiguration.class
@FeignClient(value = "feign-provider", fallbackFactory = RemoteUserFallbackFactory.class, configuration = FeignConfiguration.class)
public interface UserFeign{
@RequestMapping("/getUserById")
User getUserById(@RequestParam("id") Integer id);
}
2. http connection pool
The process of establishing an HTTP connection between two servers involves the exchange of multiple data packets, which is time-consuming. Using HTTP connection pooling can save a lot of time prompt throughput.
Feign's HTTP client supports 3 frameworks: HttpURLConnection , HttpClient , OkHttp .
Observing the source code, we can find that Feign uses java.net.HttpURLConnection by default, and each request will establish and close the connection.
2.1. Add dependencies to the feign interface project
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2.2, Open in the configuration file
feign:
# 开启 httpclient
httpclient:
enabled: true
2.3. How to verify whether it is enabled?
In feign.SynchronousMethodHandler#executeAndDecode()
this method, it can be clearly seen which client is called.
It was like this before it was turned on:
After opening:
3. gzip compression
introduce
gzip is a data format that uses the deflate algorithm to compress data; gzip is a popular file compression algorithm that is widely used, especially on the Linux platform.
ability
When Gzip compressing to a plain text file, the effect is very noticeable, about 70%+ file size reduction.
effect:
After the network data is compressed, the number of bytes transmitted by the network is actually reduced, which can speed up the loading of web pages and improve the user experience
Enable gzip compression in the consumer configuration file
server:
compression:
enabled: true #开启gzip压缩
4. feign timeout processing
When accessing a web page, it often occurs that the network is not good and the access times out. If the network timeout processing is not set in the background, and the timeout is one second and the log output is not set, the background will throw such an exception:
In the configuration file of the consumer, it can be set like this:
1、方式一:全局的处理
ribbon:
ConnectTimeout: 5000 #请求连接的超时时间
ReadTimeout: 5000 #请求处理的超时时间
2、方式二:
feign:
client:
config:
feign-provider:#这里可以写服务名,或者default默认的,全局的处理
ConnectTimeout: 5000 #请求连接的超时时间
ReadTimeout: 5000 #请求处理的超时时间
Through the above settings, you can perform timeout processing! ! !