這篇文章聊聊微服務里的這幾個老伙計:Eureka、Nacos、LoadBalance、OpenFeign。
咱們做微服務開發,總會跟這幾個組件打交道:Eureka、Nacos、Spring Cloud LoadBalancer、OpenFeign。它們各司其職又互相配合,今天就把它們的關系、用法捋清楚,再上點代碼示例,保證看完就明白。?不然很久不用就忘了。
先從注冊中心說起,這倆貨是服務的 "通訊錄"?
不管是 Eureka 還是 Nacos,核心作用都一樣:讓各個微服務能互相找到對方。服務啟動時會把自己的地址報到注冊中心,調用的時候再從注冊中心查對方的地址。但用法上差別不小。?
Eureka 得自己搭服務器,咱們用 Eureka 的話,得單獨起一個 Eureka Server 服務。步驟大概是這樣:?
- 加依賴,server 端用 spring-cloud-starter-netflix-eureka-server,client 端用 spring-cloud-starter-netflix-eureka-client。?
- 啟動類上得加 @EnableEurekaServer(服務器端),client 端不用加特殊注解但得配置。?
- 配置文件里,server 要指定自己的地址,client 要指定 server 的地址。?
舉個例子,Eureka Server 的配置:?
# application.yml
server:port: 8761
eureka:client:register-with-eureka: false # 自己不注冊自己fetch-registry: false # 不用拉取服務列表serviceUrl:defaultZone: http://localhost:8761/eureka/
啟動類:?
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApp {public static void main(String[] args) {SpringApplication.run(EurekaServerApp.class, args);}
}
?
客戶端的配置就簡單點,加個依賴,然后配置文件里指定 server 地址:?
spring:application:name: user-service # 服務名很重要,后面調用要用
eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
而 Nacos 就省事兒多了,它本身是個現成的服務器,咱們不用自己搭。直接用人家提供的 Nacos Server(可以下載安裝包啟動),咱們的服務作為 client 連上去就行。?
用法上:?
- 只需要加一個依賴:spring-cloud-starter-alibaba-nacos-discovery。?
- 配置文件里指定 Nacos Server 的地址,不用管服務器端的事兒。?
代碼示例:?
# application.yml
spring:application:name: order-servicecloud:nacos:discovery:server-addr: localhost:8848 # Nacos Server的地址
啟動類不用加特殊注解,直接啟動就行,服務會自動注冊到 Nacos。?
所以 Nacos 比 Eureka 省事兒,不用自己維護注冊中心服務器,這是最大的區別。?
再看服務調用,RestTemplate 加 LoadBalance 是基礎操作?
微服務之間調用,本質上就是發 HTTP 請求。RestTemplate 是 Spring 提供的工具,能幫咱們發請求。但直接用 RestTemplate 的話,得知道對方的 IP 和端口,這顯然不現實 —— 服務可能多實例部署,IP 端口會變。?
這時候就需要 Spring Cloud LoadBalancer 了,它能做兩件事:從注冊中心拿到服務的所有實例地址,然后根據策略(比如輪詢、隨機)選一個出來,也就是負載均衡。?
咱們用 RestTemplate+LoadBalance 的組合,就能直接用服務名調用,不用管具體 IP 了。?
步驟如下:?
- 加依賴,spring-cloud-starter-loadbalancer(Nacos 的依賴里可能已經包含,保險起見還是加上)。?
- 配置 RestTemplate 的時候,加個 @LoadBalanced 注解,告訴它要用負載均衡。?
代碼示例:?
@Configuration
public class RestTemplateConfig {@Bean@LoadBalanced // 關鍵,加上這個才能用服務名調用public RestTemplate restTemplate() {return new RestTemplate();}
}
調用的時候,直接用服務名代替 IP: 端口:?
@Service
public class OrderService {@Autowiredprivate RestTemplate restTemplate;public User getUser(Long userId) {// 直接寫 "http://服務名/接口路徑",這里的user-service就是注冊的服務名return restTemplate.getForObject("http://user-service/user/" + userId, User.class);}
}
LoadBalance 默認是輪詢策略,就是挨個調用服務實例。想改隨機的話,寫個配置類就行:?
@Configuration
public class LoadBalancerConfig {@Beanpublic ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
要是想搞更自定義的策略,比如按服務實例的負載情況分配,有兩種辦法:要么自己實現 ReactorLoadBalancer 接口,要么給 RestTemplate 加個攔截器,在攔截器里寫選擇邏輯,甚至直接在業務代碼里查服務列表再手動選。不過一般默認的或者簡單自定義就夠了。?
再說說 OpenFeign,這貨是 RestTemplate 的 "升級版"?
用 RestTemplate 調用雖然比寫死 IP 強,但還是得拼接 URL、處理響應,不夠優雅。OpenFeign 就方便多了,它是聲明式的調用工具,自帶了 LoadBalance,不用額外配置,寫起來像調本地接口一樣。?
用法步驟:?
- 加依賴,spring-cloud-starter-openfeign。?
- 啟動類上得加 @EnableFeignClients,告訴程序要掃描 Feign 接口。?
- 寫個接口,用 @FeignClient ("服務名") 標注,里面定義要調用的接口方法,路徑、參數跟服務端的接口對應上。?
- 直接注入這個接口,像用本地方法一樣調用。?
代碼示例:?
先寫 Feign 接口:?
// 聲明要調用的服務名是user-service
@FeignClient(value = "user-service")
public interface UserFeignClient {// 這里的路徑、參數要跟user-service里的接口完全一致@GetMapping("/user/{userId}")User getUser(@PathVariable("userId") Long userId);
}
啟動類加注解:?
@SpringBootApplication
@EnableFeignClients // 關鍵,開啟Feign
public class OrderApp {public static void main(String[] args) {SpringApplication.run(OrderApp.class, args);}
}
調用的時候直接用:?
@Service
public class OrderService {@Autowiredprivate UserFeignClient userFeignClient; // 注入Feign接口public User getUser(Long userId) {// 像調本地方法一樣,直接調用接口的方法return userFeignClient.getUser(userId);}
}
是不是比 RestTemplate 清爽多了?而且它自帶負載均衡,不用再操心 @LoadBalanced 的事兒,內部已經集成了。?
最后總結下它們的聯系和區別?
聯系很簡單:注冊中心是基礎,沒有它服務之間找不到對方;LoadBalance 是 "調度員",負責把請求合理分配給多個服務實例;RestTemplate 和 OpenFeign 是 "信使",負責發請求,其中 OpenFeign 封裝了 RestTemplate 和 LoadBalance,用起來更方便。?
區別主要在這幾點:?
- 注冊中心:Eureka 需要自己搭服務器,Nacos 直接用現成的,配置更簡單;Nacos 除了注冊中心還有配置中心功能,Eureka 只做注冊發現。?
- 負載均衡:LoadBalance 是單獨的負載均衡工具,RestTemplate 必須配合它才能用服務名調用;OpenFeign 自帶 LoadBalance,不用額外配置。?
- 服務調用:RestTemplate 是基礎工具,需要手動寫調用代碼;OpenFeign 是聲明式的,更簡潔,適合復雜場景。?
咱們實際開發中,現在用 Nacos+OpenFeign 的組合比較多,Nacos 省事,OpenFeign 寫起來方便。當然 RestTemplate 也得會,簡單場景下用著也挺快。?
大概就是這些了,這幾個組件配合起來,就能讓微服務之間的調用既靈活又可靠。代碼示例都給了,照著試一遍,肯定能掌握。