微服務(wù)進(jìn)行遠(yuǎn)程調(diào)用其他服務(wù)方式
前置知識:將本地服務(wù)注冊到nacos地址上:

1、服務(wù)調(diào)用
現(xiàn)在我們需要使用service-order服務(wù)調(diào)用sercice-business服務(wù)
使用@EnableDiscoveryClient注解, 開啟服務(wù)調(diào)用
引入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>需要被調(diào)用的服務(wù)啟動類:
@EnableDiscoveryClient //開啟服務(wù)調(diào)用
@SpringBootApplication
public class BusinessMainApplication{
public static void main(String[] args) {
SpringApplication.run(BusinessMainApplication.class,args);
}
}編寫需要進(jìn)行調(diào)用的接口:
@GetMapping("/business/{id}")
public Business getById(@PathVariable("id") String id){
return businessService.getBusiness(id);
}創(chuàng)建RestTemplate配置類,防止new 多個(gè)對象
@Configuration
public class OrderConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在服務(wù)層進(jìn)行調(diào)用另外一個(gè)服務(wù)
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Override
public Order getById(Long id) {
Order order = new Order();
order.setTotalAmount(new BigDecimal("1000"));
order.setNickName("尚硅谷");
order.setId(id);
order.setProductList(Lists.newArrayList());
return order;
}
@Override
public Order createOrder(Long userId, Long productId) {
//進(jìn)行遠(yuǎn)程調(diào)用獲取商品數(shù)據(jù)
Business businessById = getBusinessById(productId.toString());
Order order = new Order();
order.setId(1L);
order.setAddress("將軍大道108號");
order.setTotalAmount(BigDecimal.valueOf(businessById.getPrice() * businessById.getCount()));
order.setNickName("尚硅谷");
order.setUserId(userId);
order.setProductList(Arrays.asList(businessById));
return order;
}
/**
* 手動選擇需要的實(shí)例進(jìn)行調(diào)用
* @param businessId
* @return
*/
public Business getBusinessById(String businessId){
List<ServiceInstance> instances = discoveryClient.getInstances("service-business");
//獲取服務(wù)的第幾個(gè)實(shí)例對象
ServiceInstance instance = instances.get(0);
//端口的URL
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/business/" + businessId;
log.info("遠(yuǎn)程調(diào)用的URL:" + url);
//進(jìn)行遠(yuǎn)程調(diào)用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的數(shù)據(jù):" + forObject.toString());
return forObject;
}
}
2、負(fù)載均衡
如果被調(diào)用的服務(wù)有多個(gè)實(shí)例,現(xiàn)在我們?yōu)榱藴p輕某個(gè)服務(wù)的壓力,對服務(wù)進(jìn)行輪詢調(diào)用:
現(xiàn)在我們需要在調(diào)用方,使用loadBanlancer依賴
依賴引入:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>依賴導(dǎo)入:
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Override
public Order getById(Long id) {
Order order = new Order();
order.setTotalAmount(new BigDecimal("1000"));
order.setNickName("尚硅谷");
order.setId(id);
order.setProductList(Lists.newArrayList());
return order;
}
@Override
public Order createOrder(Long userId, Long productId) {
//進(jìn)行遠(yuǎn)程調(diào)用獲取商品數(shù)據(jù)
// Business businessById = getBusinessById(productId.toString());
// Business businessById = getBusinessByIdWithLoadBalancer(productId.toString());
Business businessById = getBusinessByIdWithAnnotation(productId.toString());
Order order = new Order();
order.setId(1L);
order.setAddress("將軍大道108號");
order.setTotalAmount(BigDecimal.valueOf(businessById.getPrice() * businessById.getCount()));
order.setNickName("尚硅谷");
order.setUserId(userId);
order.setProductList(Arrays.asList(businessById));
return order;
}
/**
* 手動選擇需要的實(shí)例進(jìn)行調(diào)用
* @param businessId
* @return
*/
public Business getBusinessById(String businessId){
List<ServiceInstance> instances = discoveryClient.getInstances("service-business");
//獲取服務(wù)的第幾個(gè)實(shí)例對象
ServiceInstance instance = instances.get(0);
//端口的URL
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/business/" + businessId;
log.info("遠(yuǎn)程調(diào)用的URL:" + url);
//進(jìn)行遠(yuǎn)程調(diào)用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的數(shù)據(jù):" + forObject.toString());
return forObject;
}
/**
* 使用LoadBalancer進(jìn)行負(fù)載均衡
* @param businessId
* @return
*/
public Business getBusinessByIdWithLoadBalancer(String businessId){
ServiceInstance choose = loadBalancerClient.choose("service-business");
//端口的URL
String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/business/" + businessId;
log.info("IP:" + choose.getHost() + ":" + choose.getPort());
log.info("遠(yuǎn)程調(diào)用的URL:" + url);
//進(jìn)行遠(yuǎn)程調(diào)用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的數(shù)據(jù):" + forObject.toString());
return forObject;
}
/**
* 使用注解@LoadBalancer進(jìn)行負(fù)載均衡
* 需要在restTemplate上添加注解LoadBalancer
* @param businessId
* @return
*/
public Business getBusinessByIdWithAnnotation(String businessId){
String url = "http://service-business/business/" + businessId;
//進(jìn)行遠(yuǎn)程調(diào)用
Business forObject = restTemplate.getForObject(url, Business.class);
log.info("返回的數(shù)據(jù):" + forObject.toString());
return forObject;
}
}
其中,第三種,使用注解的方式進(jìn)行負(fù)載均衡,需要將注解添加在restTemplate配置類上
@Configuration
public class OrderConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中HashTable和HashMap的區(qū)別_動力節(jié)點(diǎn)Java學(xué)院整理
HashTable和HashMap主要的區(qū)別有:線程安全性,同步(synchronization),以及速度。接下來通過本文給大家簡單介紹下HashTable和HashMap的區(qū)別,需要的的朋友參考下吧2017-04-04
有關(guān)Java常見的誤解小結(jié)(來看一看)
下面小編就為大家?guī)硪黄嘘P(guān)Java常見的誤解小結(jié)(來看一看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
SpringBoot項(xiàng)目中使用redis緩存的方法步驟
本篇文章主要介紹了SpringBoot項(xiàng)目中使用redis緩存的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
SpringBoot項(xiàng)目中rest接口定義與參數(shù)傳遞和接收方式
本文介紹了使用RestClient測試接口的兩種方式:form-data和content-type,form-data適用于所有請求方式,但URL長度有限制,content-type只適用于POST/DELETE/PUT請求,處理application/json格式參數(shù),對于參數(shù)較多的情況,建議使用JavaBean接收2026-04-04
Java中的服務(wù)發(fā)現(xiàn)與負(fù)載均衡及Eureka與Ribbon的應(yīng)用小結(jié)
這篇文章主要介紹了Java中的服務(wù)發(fā)現(xiàn)與負(fù)載均衡:Eureka與Ribbon的應(yīng)用,通過使用Eureka和Ribbon,我們可以在Java項(xiàng)目中實(shí)現(xiàn)高效的服務(wù)發(fā)現(xiàn)和負(fù)載均衡,需要的朋友可以參考下2024-08-08
IDEA?+?Maven環(huán)境下的SSM框架整合及搭建過程
這篇文章主要介紹了IDEA?+?Maven環(huán)境下的SSM框架整合及搭建過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
在SpringBoot項(xiàng)目中正確實(shí)現(xiàn)順序消費(fèi)的方法示例
在分布式系統(tǒng)與微服務(wù)架構(gòu)中,消息隊(duì)列已成為實(shí)現(xiàn)異步通信與服務(wù)解耦的核心基礎(chǔ)設(shè)施,然而,在許多業(yè)務(wù)場景中,消息的順序性是一個(gè)不可忽視的需求,那么,分區(qū)機(jī)制是如何工作的?在SpringBoot項(xiàng)目中如何正確實(shí)現(xiàn)順序消費(fèi)?本文將深入探討這些問題,需要的朋友可以參考下2026-04-04

