非SpringCloud項目,有時會需要調用新SpringCloud項目锻离,通過Eureka獲取動態(tài)服務地址進行遠程調用铺峭,很方便。
也可以刪除Eureka的部分汽纠,直接使用Ribbon調用卫键。
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() {
//初始化應用信息管理器,設置其狀態(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莉炉,并設置應用信息管理器的狀態(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();
//開啟一個線程驗證注冊結果
return eurekaClient;
}
}
服務配置類,目前是手動創(chuàng)建有點Low碴犬,后續(xù)可以改進為注解絮宁,使用Spring ImportBean進行改進自動創(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;
}
}
/**
* 自動創(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;
}
/**
* 手動創(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負載均衡策略實現 * 使用ZoneAvoidancePredicate和AvailabilityPredicate來判斷是否選擇某個server服协,前一個判斷判定一個zone的運行性能是否可用绍昂,
* * 剔除不可用的zone(的所有server),AvailabilityPredicate用于過濾掉連接數過多的Server偿荷。 *
*/
private IRule zoneAvoidanceRule() {
return new ZoneAvoidanceRule();
}
/**
* Ribbon負載均衡策略實現 * 隨機選擇一個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();
}
這里直接調用 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();
}
}