Eureka 的 Application Client 客戶端的運行示例

上篇以一個 demo 示例介紹了 Eureka 的 Application Service 客戶端角色。今天我們繼續瞭解 Eureka 的 Application Client 客戶端,以一個簡單的交互示例,介紹 Application Client 是如何使用 Eureka 獲取 Application Service 實例併發送請求的。
        上篇《Eureka 的 Application Service 客戶端的註冊以及運行示例》使用了一個 Socket 服務做爲 demo,本文示例配合該文,將以一個 Socket 客戶端對該服務進行請求。
        1. Eureka 服務器啓動
        本文 demo 要求 Eureka Server 已經部署好,並已經啓動。關於架設步驟參考博客《Linux 下 Eureka 服務器的部署》。
        2. Application Service 服務啓動
        直接將《Eureka 的 Application Service 客戶端的註冊以及運行示例》中的小 demo 跑起來(Socket Server 啓動,開始侍服網絡請求)。
        3. Application Client 配置文件的編寫
        我們的 Application Client 就用官方提供 demo 裏的 sampleclient 下的 sample-eureka-client.properties 即可,當然還要根據實際情況修正一下,比如把 eureka.serviceUrl.default(默認情況下本客戶端將要註冊到的 Eureka 服務器):http://serverIP:8080/eureka/v2/
[plain] view plain copy
 print?
  1. ###Eureka Client configuration for Sample Eureka Client  
  2.   
  3.   
  4. #Properties based configuration for eureka client. The properties specified here is mostly what the users  
  5. #need to change. All of these can be specified as a java system property with -D option (eg)-Deureka.region=us-east-1  
  6. #For additional tuning options refer <url to go here>  
  7.   
  8.   
  9.   
  10.   
  11. #Region where eureka is deployed -For AWS specify one of the AWS regions, for other datacenters specify a arbitrary string  
  12. #indicating the region.This is normally specified as a -D option (eg) -Deureka.region=us-east-1  
  13. eureka.region=default  
  14.   
  15.   
  16. #Name of the application to be identified by other services  
  17.   
  18.   
  19. eureka.name=sampleEurekaClient  
  20.   
  21.   
  22. #Virtual host name by which the clients identifies this service  
  23. #eureka.vipAddress=eureka.mydomain.net  
  24.   
  25.   
  26. #The port where the service will be running and servicing requests  
  27. #eureka.port=80  
  28.   
  29.   
  30. #For eureka clients running in eureka server, it needs to connect to servers in other zones  
  31. eureka.preferSameZone=true  
  32.   
  33.   
  34. #Change this if you want to use a DNS based lookup for determining other eureka servers. For example  
  35. #of specifying the DNS entries, check the eureka-client-test.properties, eureka-client-prod.properties  
  36. eureka.shouldUseDns=false  
  37.   
  38.   
  39. eureka.us-east-1.availabilityZones=default  
  40.   
  41.   
  42. eureka.serviceUrl.default=http://serverIP:8080/eureka/v2/  

        4. 日誌配置
        就用官方提供 demo 裏的 sampleclient 下的 log4j.properties 即可,當然還要根據實際需要修正一下,比如給 com.netflix.eureka 包的輸出級別設置爲 DEBUG(log4j.properties 追加 log4j.logger.com.netflix.eureka=DEBUG),以方便我們研發期跟蹤調試。
[plain] view plain copy
 print?
  1. log4j.rootCategory=INFO,stdout  
  2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
  4. log4j.appender.stdout.layout.ConversionPattern=%d %-5p %C:%L [%t] [%M] %m%n  
  5. log4j.logger.com.netflix.eureka=DEBUG  

        5. 尋找本次請求的 Application Service 實例
        客戶端在向 Application Service 請求之前得先從 Eureka Server 拿到侍服本次請求的 Application Service 實例。尋找本次請求的 Application Service 實例的代碼如下:
[java] view plain copy
 print?
  1. // Register with Eureka  
  2. DiscoveryManager.getInstance().initComponent(  
  3.         new MyDataCenterInstanceConfig(),  
  4.         new DefaultEurekaClientConfig());  
  5. ApplicationInfoManager.getInstance().setInstanceStatus(  
  6.         InstanceStatus.UP);  
  7. String vipAddress = configInstance.getStringProperty(  
  8.         "eureka.vipAddress""sampleservice.mydomain.net").get();  
  9. InstanceInfo nextServerInfo = DiscoveryManager.getInstance()  
  10.         .getDiscoveryClient()  
  11.         .getNextServerFromEureka(vipAddress, false);  

        第一句初始化本客戶端,第二句告訴 Eureka 本客戶端處於就緒狀態,接下來兩句是使用 Eureka 找到對本次請求進行侍服的 Application Service 實例。
        6. Application Client 網絡請求
        Application Client 拿到 Application Service 之後立馬進行網絡 Socket 請求,進行數據信息交互。
[java] view plain copy
 print?
  1. Socket s = new Socket();  
  2. int serverPort = nextServerInfo.getPort();  
  3. try {  
  4.     s.connect(new InetSocketAddress(nextServerInfo.getHostName(),  
  5.             serverPort));  
  6. catch (IOException e) {  
  7.     System.err.println("Could not connect to the server :"  
  8.             + nextServerInfo.getHostName() + " at port " + serverPort);  
  9. }  
  10. try {  
  11.     System.out.println("Connected to server. Sending a sample request");  
  12.     PrintStream out = new PrintStream(s.getOutputStream());  
  13.     out.println("Sample request " + new Date());  
  14.     String str = null;  
  15.     System.out.println("Waiting for server response..");  
  16.     BufferedReader rd = new BufferedReader(new InputStreamReader(  
  17.             s.getInputStream()));  
  18.     str = rd.readLine();  
  19.     if (str != null) {  
  20.         System.out  
  21.                 .println("Received response from server. Communication all fine using Eureka :");  
  22.         System.out.println("Exiting the client. Demo over..");  
  23.     }  
  24.     rd.close();  
  25. catch (IOException e) {  
  26.     e.printStackTrace();  
  27. }  

        7. Application Client 關閉時取消註冊
        Application Client 在關閉時要將自己在 Eureka 的註冊取消掉。
[java] view plain copy
 print?
  1. public void unRegisterWithEureka() {  
  2.     // Un register from eureka.  
  3.     DiscoveryManager.getInstance().shutdownComponent();  
  4. }  

        8. 運行 demo
        新建一個項目(不要和 Application Service 的 demo 跑在同一個項目下),現在我們把完整的 Application Client 代碼整理一下。
[java] view plain copy
 print?
  1. /* 
  2.  * Copyright 2012 Netflix, Inc. 
  3.  * 
  4.  *    Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  *    you may not use this file except in compliance with the License. 
  6.  *    You may obtain a copy of the License at 
  7.  * 
  8.  *        http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  *    Unless required by applicable law or agreed to in writing, software 
  11.  *    distributed under the License is distributed on an "AS IS" BASIS, 
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  *    See the License for the specific language governing permissions and 
  14.  *    limitations under the License. 
  15.  */  
  16.   
  17.   
  18. package com.netflix.eureka;  
  19.   
  20.   
  21. import java.io.BufferedReader;  
  22. import java.io.IOException;  
  23. import java.io.InputStreamReader;  
  24. import java.io.PrintStream;  
  25. import java.net.InetSocketAddress;  
  26. import java.net.Socket;  
  27. import java.util.Date;  
  28.   
  29.   
  30. import org.slf4j.Logger;  
  31. import org.slf4j.LoggerFactory;  
  32.   
  33.   
  34. import com.netflix.appinfo.ApplicationInfoManager;  
  35. import com.netflix.appinfo.InstanceInfo;  
  36. import com.netflix.appinfo.InstanceInfo.InstanceStatus;  
  37. import com.netflix.appinfo.MyDataCenterInstanceConfig;  
  38. import com.netflix.config.DynamicPropertyFactory;  
  39. import com.netflix.discovery.DefaultEurekaClientConfig;  
  40. import com.netflix.discovery.DiscoveryManager;  
  41.   
  42.   
  43. /** 
  44.  * Sample Eureka client that discovers the service using Eureka and sends 
  45.  * requests. 
  46.  * 
  47.  * @author Karthik Ranganathan 
  48.  * 
  49.  */  
  50. public class SampleEurekaClient {  
  51.     private static final DynamicPropertyFactory configInstance = com.netflix.config.DynamicPropertyFactory  
  52.             .getInstance();  
  53.       
  54.     private static final Logger logger = LoggerFactory  
  55.     .getLogger(SampleEurekaClient.class);  
  56.   
  57.   
  58.     public void sendRequestToServiceUsingEureka() {  
  59.         // Register with Eureka  
  60.         DiscoveryManager.getInstance().initComponent(  
  61.                 new MyDataCenterInstanceConfig(),  
  62.                 new DefaultEurekaClientConfig());  
  63.         ApplicationInfoManager.getInstance().setInstanceStatus(  
  64.                 InstanceStatus.UP);  
  65.         String vipAddress = configInstance.getStringProperty(  
  66.                 "eureka.vipAddress""sampleservice.mydomain.net").get();  
  67.         InstanceInfo nextServerInfo = DiscoveryManager.getInstance()  
  68.                 .getDiscoveryClient()  
  69.                 .getNextServerFromEureka(vipAddress, false);  
  70.   
  71.   
  72.         Socket s = new Socket();  
  73.         int serverPort = nextServerInfo.getPort();  
  74.         try {  
  75.             s.connect(new InetSocketAddress(nextServerInfo.getHostName(),  
  76.                     serverPort));  
  77.         } catch (IOException e) {  
  78.             System.err.println("Could not connect to the server :"  
  79.                     + nextServerInfo.getHostName() + " at port " + serverPort);  
  80.         }  
  81.         try {  
  82.             System.out.println("Connected to server. Sending a sample request");  
  83.             PrintStream out = new PrintStream(s.getOutputStream());  
  84.             out.println("Sample request " + new Date());  
  85.             String str = null;  
  86.             System.out.println("Waiting for server response..");  
  87.             BufferedReader rd = new BufferedReader(new InputStreamReader(  
  88.                     s.getInputStream()));  
  89.             str = rd.readLine();  
  90.             if (str != null) {  
  91.                 System.out  
  92.                         .println("Received response from server. Communication all fine using Eureka :");  
  93.                 System.out.println("Exiting the client. Demo over..");  
  94.             }  
  95.             rd.close();  
  96.         } catch (IOException e) {  
  97.             e.printStackTrace();  
  98.         }  
  99.         this.unRegisterWithEureka();  
  100.     }  
  101.   
  102.   
  103.     public void unRegisterWithEureka() {  
  104.         // Un register from eureka.  
  105.         DiscoveryManager.getInstance().shutdownComponent();  
  106.     }  
  107.   
  108.   
  109.     public static void main(String[] args) {  
  110.         SampleEurekaClient sampleEurekaService = new SampleEurekaClient();  
  111.         sampleEurekaService.sendRequestToServiceUsingEureka();  
  112.   
  113.   
  114.     }  
  115.   
  116.   
  117. }  

        如上篇博客所述一樣把各種依賴包加進本文 demo 的 CLASSPATH,然後把第三、四步寫好的 sample-eureka-client.properties、log4j.properties 也拷貝進 CLASSPATH,並將 sample-eureka-client.properties 重命名爲 config.properties(原因參考上篇博客),接下來就可以運行本文 demo 了。run SampleEurekaClient,日誌結果如下:
2014-07-10 11:02:51,860 INFO  com.netflix.config.sources.URLConfigurationSource:125 [main] [<init>] URLs to be used as dynamic configuration source: [file:/D:/javaprojects/test2/bin/config.properties]
2014-07-10 11:02:51,927 INFO  com.netflix.config.DynamicPropertyFactory:281 [main] [getInstance] DynamicPropertyFactory is initialized with configuration sources: com.netflix.config.ConcurrentCompositeConfiguration@5ca46701
2014-07-10 11:02:52,060 WARN  com.netflix.appinfo.PropertiesInstanceConfig:349 [main] [init] Cannot find the properties specified : eureka-client. This may be okay if there are other environment specific properties or the configuration is installed with a different mechanism.
2014-07-10 11:02:52,065 WARN  com.netflix.discovery.DefaultEurekaClientConfig:95 [main] [init] Cannot find the properties specified : eureka-client. This may be okay if there are other environment specific properties or the configuration is installed with a different mechanism.
2014-07-10 11:02:52,103 INFO  com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider:79 [main] [get] Setting initial instance status as: STARTING
2014-07-10 11:02:53,667 INFO  com.netflix.discovery.DiscoveryClient:646 [main] [fetchRegistry] Disable delta property : false
2014-07-10 11:02:53,667 INFO  com.netflix.discovery.DiscoveryClient:647 [main] [fetchRegistry] Single vip registry refresh property : null
2014-07-10 11:02:53,667 INFO  com.netflix.discovery.DiscoveryClient:648 [main] [fetchRegistry] Force full registry fetch : false
2014-07-10 11:02:53,667 INFO  com.netflix.discovery.DiscoveryClient:649 [main] [fetchRegistry] Application is null : false
2014-07-10 11:02:53,667 INFO  com.netflix.discovery.DiscoveryClient:650 [main] [fetchRegistry] Registered Applications size is zero : true
2014-07-10 11:02:53,668 INFO  com.netflix.discovery.DiscoveryClient:652 [main] [fetchRegistry] Application version is -1: true
2014-07-10 11:02:54,061 INFO  com.netflix.discovery.DiscoveryClient:992 [main] [makeRemoteCall] Finished a call to service url http://serverIP:8080/eureka/v2/ and url path apps/ with status code 200.
2014-07-10 11:02:54,061 INFO  com.netflix.discovery.DiscoveryClient:758 [main] [getAndStoreFullRegistry] Getting all instance registry info from the eureka server
2014-07-10 11:02:54,568 INFO  com.netflix.discovery.DiscoveryClient:765 [main] [getAndStoreFullRegistry] The response status is 200
2014-07-10 11:02:54,578 INFO  com.netflix.discovery.DiscoveryClient:1056 [main] [initScheduledTasks] Starting heartbeat executor: renew interval is: 30
Connected to server. Sending a sample request
Waiting for server response..
Received response from server. Communication all fine using Eureka :
Exiting the client. Demo over..

        證明 demo 獲取 Application Service 實例並請求成功。
        可以看出,Application Service 實例的信息都封裝在了 com.netflix.appinfo.InstanceInfo 下,那麼我們還能從中獲取哪些信息?SampleEurekaClient 類加入以下代碼:
[java] view plain copy
 print?
  1. logger.debug("nextServerInfo.getAppGroupName()-" + nextServerInfo.getAppGroupName());  
  2. logger.debug("nextServerInfo.getAppName()-" + nextServerInfo.getAppName());  
  3. logger.debug("nextServerInfo.getASGName()-" + nextServerInfo.getASGName());  
  4. logger.debug("nextServerInfo.getHomePageUrl()-" + nextServerInfo.getHomePageUrl());  
  5. logger.debug("nextServerInfo.getHostName()-" + nextServerInfo.getHostName());  
  6. logger.debug("nextServerInfo.getId()-" + nextServerInfo.getId());  
  7. logger.debug("nextServerInfo.getIPAddr()-" + nextServerInfo.getIPAddr());  
  8. logger.debug("nextServerInfo.getLastUpdatedTimestamp()-" + nextServerInfo.getLastUpdatedTimestamp());  
  9. logger.debug("nextServerInfo.getPort()-" + nextServerInfo.getPort());  
  10. logger.debug("nextServerInfo.getSecureVipAddress()-" + nextServerInfo.getSecureVipAddress());  
  11. logger.debug("nextServerInfo.getStatusPageUrl()-" + nextServerInfo.getStatusPageUrl());  
  12. logger.debug("nextServerInfo.getVIPAddress()-" + nextServerInfo.getVIPAddress());  
  13. logger.debug("nextServerInfo.getLastDirtyTimestamp()-" + nextServerInfo.getLastDirtyTimestamp());  
  14. logger.debug("nextServerInfo.getHealthCheckUrls()-" + nextServerInfo.getHealthCheckUrls());  
  15. logger.debug("nextServerInfo.getStatus()-" + nextServerInfo.getStatus());  

        然後重新運行本文 demo,以上語句打印結果如下:
2014-07-10 11:02:54,619 DEBUG com.netflix.eureka.SampleEurekaClient:69 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getAppGroupName()-UNKNOWN
2014-07-10 11:02:54,619 DEBUG com.netflix.eureka.SampleEurekaClient:70 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getAppName()-SAMPLESERVICE
2014-07-10 11:02:54,619 DEBUG com.netflix.eureka.SampleEurekaClient:71 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getASGName()-null
2014-07-10 11:02:54,619 DEBUG com.netflix.eureka.SampleEurekaClient:72 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getHomePageUrl()-http://defonds-win7:1935/
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:73 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getHostName()-defonds-win7
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:74 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getId()-defonds-win7
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:75 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getIPAddr()-172.21.40.134
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:76 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getLastUpdatedTimestamp()-1404961202884
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:77 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getPort()-1935
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:78 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getSecureVipAddress()-null
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:79 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getStatusPageUrl()-http://defonds-win7:1935/Status
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:80 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getVIPAddress()-sampleservice.mydomain.net
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:81 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getLastDirtyTimestamp()-1404961230856
2014-07-10 11:02:54,620 DEBUG com.netflix.eureka.SampleEurekaClient:82 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getHealthCheckUrls()-[http://defonds-win7:1935/healthcheck]
2014-07-10 11:02:54,621 DEBUG com.netflix.eureka.SampleEurekaClient:83 [main] [sendRequestToServiceUsingEureka] nextServerInfo.getStatus()-UP

        這些信息都和 http://serverIP:8080/eureka/v2/apps/ 顯示的 SAMPLESERVICE 實例的 各個屬性一一對應。
        參考資料
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章