微服务springcloud使用openfeign进行服务调用

1. 添加依赖

<!-- spring cloud openfeign -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
		</dependency>

2. 启动类添加注解

@EnableFeignClients(basePackages={"com.demo.feign"})

启用feign客户端。 

3. 添加Feign接口

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;

import com.demo.entity.GetTokenRequest;
import com.demo.entity.TokenResponse;

// @FeignClient(contextId = "demo-authserver-token", value = "demo-authserver")
@FeignClient(name = "demo-authserver", 
configuration = FeignConfiguration.class, fallback=GetTokenServiceFallback.class)
public interface GetTokenService {
	
	@GetMapping(value = "/getToken")
    public String getTokenInfo(@RequestBody GetTokenRequest tokenRequest);

}

@FeignClient的注解参数说明:

value和name:value和name的作用一样,如果没有配置url那么配置的值将作为服务名称,用于服务发现。反之只是一个名称;

serviceId:serviceId已经废弃了,直接使用name即可。

contextId:一个相同的服务定义的接口比较多,当需要定义多个feign接口进行分组时,就可以添加该参数;获取客户端名称时,如果配置了contextId就会用contextId,如果没有配置就会去value,然后是name,最后是serviceId。默认都没有配置,当出现一个服务有多个Feign Client的时候就会报错了。

String name = getClientName(attributes);

registerClientConfiguration(registry, name,
attributes.get("configuration"));

private String getClientName(Map<String, Object> client) {
    if (client == null) {
      return null;
    }
    String value = (String) client.get("contextId");
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("value");
    }
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("name");
    }
    if (!StringUtils.hasText(value)) {
      value = (String) client.get("serviceId");
    }
    if (StringUtils.hasText(value)) {
      return value;
    }


    throw new IllegalStateException("Either 'name' or 'value' must be provided in @"
        + FeignClient.class.getSimpleName());
  }

url:url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用;

configuration:指定feign的配置类,可以自定义Feign的Encoder、Decoder、LogLevel(定义日志)、Contract;

fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口;

path:定义当前FeignClient的统一前缀,当我们项目中配置了server.context-path,server.servlet-path时使用

4. feign配置类

public class FeignConfiguration {
    @Bean
    public Logger.Level getLoggerLevel() {
        return Logger.Level.FULL;
    }
    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }

    @Bean
    public Request.Options options(){
        return new Request.Options(5000, 3000);
    }

    @Bean
    public CustomRequestInterceptor customRequestInterceptor() {
        return new CustomRequestInterceptor();
    }
    // Contract,feignDecoder,feignEncoder.....
}

5. 定义容错的处理类

@Component
public class GetTokenServiceFallback implements GetTokenService {
    @Override
    public String getTokenInfo(@RequestBody GetTokenRequest tokenRequest);
    {
        TokenResponse tokenResponse = new TokenResponse();
    	
    	tokenResponse.setCode("9999");
    	tokenResponse.setMessage("令牌获取失败");

        String jsonTokenResponse = JSONObject.toJSONString(tokenResponse);

        return jsonTokenResponse;
    }
}

 fallback的类必须实现Feign Client的接口。

6. 执行调用

@RestController
public class GetTokenController {
	
	@Autowired
    private GetTokenService getTokenService;

    /**
     * 获取当前用户信息
     */
    @GetMapping("/tokeninfo/{username}")
    public Object tokeninfo(@PathVariable("username") String username)
    {
    	GetTokenRequest tokenRequest = new GetTokenRequest();
    		
		tokenRequest.setAppid("appftcsp001");
		tokenRequest.setDatetime("20200818160101");
		tokenRequest.setNonce("98908999");		
		tokenRequest.setTokentype("md5");		
				
		String data = tokenRequest.getDatetime() + tokenRequest.getAppid() + tokenRequest.getNonce() + tokenRequest.getTokentype();
				String appSecret = "appkeyftcsp001";
		
		String hash = Md5Utils.hash(data + appSecret);		
		tokenRequest.setSign(hash);
    	String tokenInfo = getTokenService.getTokenInfo(tokenRequest);
    	
    	return tokenInfo;
    }

}

7. 通过配置文件配置参数

logging:
  level:
    com.demo.openfeign.feignapi: debug

feign:
  client:
    config:
      demo-authserver:
        # 日志级别配置
        loggerLevel: FULL
        # 连接超时时间
        connectTimeout: 5000
        # 请求处理超时时间
        readTimeout: 300

使用openfeign进行简单的调用还是比较容易的,相比固定的接口地址调用,使用服务名进行调用,配合ribbon的负载均衡策略,可以实现负载均衡功能。需要关注的是调用失败处理,调用日志,超时时间,自定义拦截器等内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值