一、Spring环境中Feign+Ribbon的使用
RemoteService:就是自定义的远程调用接口
import com.sam.demo.entity.User;
import feign.Headers;
import feign.RequestLine;
public interface RemoteService {
@RequestLine("POST /users/list")
@Headers({
"Content-Type: application/json",
"Accept: application/json",
"request-token: {requestToken}",
"UserId: {userId}",
"UserName: {userName}"
})
public User getOwner(@RequestBody User user,
@Param("requestToken") String requestToken,
@Param("userId") Long userId,
@Param("userName") String userName);
}
在Springboot中使用@Bean对远程调用接口定义
import java.io.IOException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.client.ClientFactory;
import com.netflix.client.config.IClientConfig;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import com.sam.demo.service.RemoteService;
import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.ribbon.LBClient;
import feign.ribbon.LBClientFactory;
import feign.ribbon.RibbonClient;
@Configuration
public class FeignConfig {
public FeignConfig() {
try {
ConfigurationManager.loadPropertiesFromResources("sample-client.properties");
} catch (IOException e) {
e.printStackTrace();
}
}
@Bean
public RemoteService remoteService() {
RibbonClient client = RibbonClient.builder().lbClientFactory(new LBClientFactory() {
@Override
public LBClient create(String clientName) {
IClientConfig config = ClientFactory.getNamedConfig(clientName);
ILoadBalancer lb = ClientFactory.getNamedLoadBalancer(clientName);
ZoneAwareLoadBalancer zb = (ZoneAwareLoadBalancer) lb;
zb.setRule(zoneAvoidanceRule());
return LBClient.create(lb, config);
}
}).build();
return Feign.builder()
.client(client)
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(RemoteService.class, "http://sample-client/gradle-web");
}
/**
* Ribbon负载均衡策略实现
* 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,
* 剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。
* @return
*/
private IRule zoneAvoidanceRule() {
return new ZoneAvoidanceRule();
}
/**
* Ribbon负载均衡策略实现
* 随机选择一个server。
* @return
*/
private IRule randomRule() {
return new RandomRule();
}
在需要使用远程接口的地方,注入该接口即可。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.sam.demo.entity.User;
import com.sam.demo.service.RemoteService;
@RestController
public class RemoteController {
@Autowired
private RemoteService remoteService;
@RequestMapping(value="/remote",method={RequestMethod.GET})
public String list() {
User user = new User();
user.setUsername("scott");
user = remoteService.getOwner(user);
return user.getUsername();
}
}
Feign1
Feign2
Feign3
https://github.com/OpenFeign/feign