SpringCloud Alibaba 2021微服务实战二十五 openfeign最佳实践

1,依赖pom

<?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">
    <parent>
        <artifactId>cloud_alibaba_learn</artifactId>
        <groupId>com.liu.learn</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud_order</artifactId>

    <dependencies>

       
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>


    </dependencies>


</project>

配置文件

server:
  port: 8090
spring:
  #profiles:
    #active: dev
  application:
    main:
      allow-bean-definition-overriding: true
    name: order-service #服务名
    cloud:
      nacos:
        discovery:
          server-addr: 127.0.0.1:8848
feign:
  sentinel:
    #为feign整合Sentinel
    enabled: true
    okhttp:
    enabled: true
  httpclient:
    enabled: false
    max-connections: 1000
    max-connections-per-route: 100
server:
  undertow:
    max-http-post-size: 0
    # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程,数量和CPU 内核数目一样即可
    io-threads: 4
    # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载  io-threads*8
    worker-threads: 32
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分
    buffer-size: 1024
    # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region
    #   buffers-per-region: 1024 # 这个参数不需要写了
    # 是否分配的直接内存
    direct-buffers: true

 

feign客户端





import com.liu.consts.SecurityConstants;
import com.liu.consts.ServiceNameConstants;
import com.liu.entity.SysLog;
import com.liu.feign.factory.RemoteLogServiceFallbackFactory;
import com.liu.rs.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
//value = ServiceNameConstants.LOG_SERVICE 改为自己服务名
//CommonResult 返回值类
@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.LOG_SERVICE,
		fallbackFactory = RemoteLogServiceFallbackFactory.class)
public interface RemoteLogService {

	/**
	 * 保存日志
	 * @param sysLog 日志实体
	 * @param from 内部调用标志
	 * @return succes、false
	 */
	@PostMapping("/log")
    CommonResult saveLog(@RequestBody SysLog sysLog, @RequestHeader(SecurityConstants.FROM) String from);

}
import com.liu.feign.RemoteLogService;
import com.liu.feign.fallback.RemoteLogServiceFallbackImpl;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;


@Component
public class RemoteLogServiceFallbackFactory implements FallbackFactory<RemoteLogService> {

	@Override
	public RemoteLogService create(Throwable throwable) {
		RemoteLogServiceFallbackImpl remoteLogServiceFallback = new RemoteLogServiceFallbackImpl();
		remoteLogServiceFallback.setCause(throwable);
		return remoteLogServiceFallback;
	}

}
import com.liu.entity.SysLog;
import com.liu.feign.RemoteLogService;
import com.liu.rs.CommonResult;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class RemoteLogServiceFallbackImpl implements RemoteLogService {

	@Setter
	private Throwable cause;

	/**
	 * 保存日志
	 * @param sysLog 日志实体
	 * @param from 内部调用标志
	 * @return succes、false
	 */
	@Override
	public CommonResult saveLog(SysLog sysLog, String from) {

		log.error("feign 插入日志失败,{}", cause.getMessage());
		cause.printStackTrace();
		log.error("feign 插入日志失败,{}", cause.getLocalizedMessage());
		return null;
	}

}
  1. fallback和fallbackFactory是有一定的冲突的,你可以理解为fallbackFactory是fallback的一个增强版,


  2. 因为fallback只是复写方法 ,没办法打印日志,而这个更强一点,fallbackFactory可以拦截异常这一块

上一篇:本地数据库创建用户+表空间等


下一篇:分析应用 - 自动化失败原因