非SpringCloud項(xiàng)目,有時(shí)會(huì)需要調(diào)用新SpringCloud項(xiàng)目,通過(guò)Eureka獲取動(dòng)態(tài)服務(wù)地址進(jìn)行遠(yuǎn)程調(diào)用,很方便。
也可以刪除Eureka的部分,直接使用Ribbon調(diào)用。
EurekaClient 初始化類
/**
* @author slankka
*/
@Configuration
public class EurekaClientConfiguration {
Logger log = LoggerFactory.getLogger(getClass());
private static ApplicationInfoManager applicationInfoManager;
private static EurekaClient eurekaClient;
private static synchronized ApplicationInfoManager initializeApplicationInfoManager(
EurekaInstanceConfig instanceConfig) {
if (applicationInfoManager == null) {
InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig)
.get();
applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo);
}
return applicationInfoManager;
}
private static synchronized EurekaClient initializeEurekaClient(
ApplicationInfoManager applicationInfoManager, EurekaClientConfig clientConfig) {
if (eurekaClient == null) {
eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);
}
return eurekaClient;
}
@Bean(destroyMethod = "shutdown")
public EurekaClient eurekaClient() {
//初始化應(yīng)用信息管理器,設(shè)置其狀態(tài)為STARTING
applicationInfoManager = initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.STARTING);
log.info("Registering service to eureka with status STARTING");
//讀取配置文件(classpath:eureka-client.properties),初始化eurekaClient,并設(shè)置應(yīng)用信息管理器的狀態(tài)為UP
eurekaClient = initializeEurekaClient(applicationInfoManager,
new DefaultEurekaClientConfig());
DiscoveryManager.getInstance().setDiscoveryClient((DiscoveryClient) eurekaClient);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.UP);
log.info("Initialization finished, now changing eureka client status to UP");
long startTime = System.currentTimeMillis();
//開啟一個(gè)線程驗(yàn)證注冊(cè)結(jié)果
return eurekaClient;
}
}
服務(wù)配置類,目前是手動(dòng)創(chuàng)建有點(diǎn)Low,后續(xù)可以改進(jìn)為注解,使用Spring ImportBean進(jìn)行改進(jìn)自動(dòng)創(chuàng)建Bean。
/**
* @author slankka
*/
@Configuration
public class RemoteServiceConfiguration {
Logger log = LoggerFactory.getLogger(RemoteServiceConfiguration.class);
public RemoteServiceConfiguration() {
try {
//這里讀取其他配置
ConfigurationManager.loadPropertiesFromResources("config.properties");
} catch (IOException e) {
e.printStackTrace();
}
}
@Autowired
private EurekaClient eurekaClient;
class EurekaClientProvider implements Provider<EurekaClient> {
@Override
public EurekaClient get() {
return eurekaClient;
}
}
/**
* 自動(dòng)創(chuàng)建Ribbon
* @return
*/
@Bean
public RibbonClientRemote remoteService() {
InstanceInfo nextServerFromEureka = eurekaClient
.getNextServerFromEureka("APOLLO-CONFIGSERVICE", false);
log.error("------------------------,APOLLO-CONFIGSERVICE= {}:{}",
nextServerFromEureka.getIPAddr(), nextServerFromEureka.getPort());
RibbonClientRemote service = Feign.builder().client(RibbonClient.create())
.logger(new Slf4jLogger()).logLevel(Level.FULL).encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(RibbonClientRemote.class, "http://APOLLO-CONFIGSERVICE");
return service;
}
/**
* 手動(dòng)創(chuàng)建Ribbon
*/
public RibbonClientRemote remoteServiceManuallyMade() {
IRule rule = new AvailabilityFilteringRule();
ServerList<DiscoveryEnabledServer> list = new DiscoveryEnabledNIWSServerList("APOLLO-CONFIGSERVICE", new EurekaClientProvider());
ServerListFilter<DiscoveryEnabledServer> filter = new ZoneAffinityServerListFilter<DiscoveryEnabledServer>();
ZoneAwareLoadBalancer<DiscoveryEnabledServer> lb = LoadBalancerBuilder.<DiscoveryEnabledServer>newBuilder()
.withDynamicServerList(list)
.withRule(rule)
.withServerListFilter(filter)
.buildDynamicServerListLoadBalancer();
RibbonClient client = RibbonClient.builder().lbClientFactory(new LBClientFactory() {
@Override
public LBClient create(String clientName) {
return LBClient.create(lb, ClientFactory.getNamedConfig(clientName));
}
}).build();
RibbonClientRemote service = Feign.builder().client(client).logger(new Slf4jLogger()).logLevel(Level.FULL).encoder(new JacksonEncoder())
.decoder(new JacksonDecoder()).target(RibbonClientRemote.class, "http://APOLLO-CONFIGSERVICE");
return service;
}
/**
* * Ribbon負(fù)載均衡策略實(shí)現(xiàn) * 使用ZoneAvoidancePredicate和AvailabilityPredicate來(lái)判斷是否選擇某個(gè)server,前一個(gè)判斷判定一個(gè)zone的運(yùn)行性能是否可用,
* * 剔除不可用的zone(的所有server),AvailabilityPredicate用于過(guò)濾掉連接數(shù)過(guò)多的Server。 *
*/
private IRule zoneAvoidanceRule() {
return new ZoneAvoidanceRule();
}
/**
* Ribbon負(fù)載均衡策略實(shí)現(xiàn) * 隨機(jī)選擇一個(gè)server。 *
*/
private IRule randomRule() {
return new RandomRule();
}
}
Feign接口
/**
* @Author: slankka
* @Date: 2018/08/08 10:24.
*/
public interface RibbonClientRemote {
@Headers({"Content-Type: application/json", "Accept: application/json"})
@RequestLine("GET /info")
InfoBean info();
}
這里直接調(diào)用 APOLLO-CONFIGSERVICE/info
Controller類
/**
* @Author: slankka
* @Date: 2018/08/04 22:25.
*/
@RequestMapping("/core")
@Controller
public class CoreController {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private RibbonClientRemote ribbonClientRemote;
@RequestMapping("/raw")
@ResponseBody
public String respone() {
return "{\"code\":200,\"msg\":\"你好中文\",\"data\":null}";
}
@RequestMapping("/ribbon")
@ResponseBody
public InfoBean ribbon() {
return ribbonClientRemote.info();
}
}