去年寫了dubbo源碼解析系列,可是由於一些不可抗拒的因素(加班),致使通訊、編解碼部分還沒寫.同時在和不少朋友交流過程當中,其中反饋最多的一個問題是.看源碼到底有什麼用?到底是不是真的只是面試時裝裝逼,裝完繼續CRUD.java
其實之因此有這樣的疑問,主要是由於平時遇到的問題都能經過搜索引擎解決.然而,我近兩年的作的都是基礎平臺相關的工做,仍是常常遇到一些必需要看源碼才能解決的問題.因此我以爲光把本身看源碼的經驗分享出來還不夠,更重要是講清楚,看源碼,究竟解決了什麼實際問題.linux
本篇是爲何要看源碼系列
的第三篇.先交代一下背景面試
因爲公司作的是海外業務,爲了方便海外同事辦公.咱們把公司的開發服務器(如下簡稱sit環境)遷移到了海外.可是這樣就產生了一個問題.因爲服務器在海外,運維部表示因爲政策緣由(具體細節不透露),那麼咱們將沒法訪問到sit環境.既然沒法訪問,那麼這個sit環境對於咱們就形同虛設了.通過協調.運維用Nginx作端口轉發.把咱們經常使用的中間件(zookeeper,RocketMQ)、數據庫地址作映射.可是這樣依然存在一些問題,下面畫圖分析數據庫
其實咱們常見的中間件的原理都大體相同,你瞭解一種後,經過類比學習.很容易掌握其餘的.下面拿RocketMQ舉例.演示一下什麼叫類比學習法編程
RocketMQ的官方文檔中物理部署結構圖以下:api
NameSever
你可能不知道是什麼.其實這個是RocketMQ3.X版本引入的,以前用的是zookeeper.就是說,3.X版本發現zookeeper功能很強大, 可是人家其實用不到zookeeper這麼多功能,基本上只用到了zookeeper的分佈式協調,也就是註冊中心的功能,就弄了個更輕量的NameSever
.服務器
那麼Broker
是什麼呢? 這個是數據存儲的核心,也是真正的MQ服務器.咱們所謂的消息存儲,接收,拉取,推送操做都是在這個broker進行的.網絡
簡單的說,咱們平時在項目中配置的mq地址是NameSever
.而後Broker
把信息註冊到NameSever
.在框架的底層,咱們訪問NameSever
的時候,它經過註冊的信息真正發起網絡請求去訪問註冊的Broker
.app
那麼接下來咱們就類比一下fastDFS
框架
從上面兩個圖你就能夠看出.在fastDFS
中,Tracker Server
就相似NameSever
,Storage Server
就相似Broker
.原理基本是同樣的.一樣的,平時咱們項目中配置的地址實際上是Tracker Server
的地址
Dubbo的原理我這裏就不想再多作解釋了,以前已經從源碼角度各類剖析了.這裏給以前沒看過我Dubbo源碼解析的朋友簡單科普一下(真的只是簡單講兩句)
兩個Dubbo服務之間的調用,絕大多數狀況是網絡調用(爲何是絕大多數.由於這個涉及到本地暴露和遠程暴露的問題).那麼網絡調用,至少要肯定三個參數.就是
url地址
請求參數
響應參數
因此Dubbo最簡單的原理就是,生產者把本機的ip地址和暴露的接口信息在zookeeper上建立節點.由於本機的ip地址就能夠肯定請求的url地址,接口信息能夠肯定請求和響應的參數.而後消費者調用接口的時候,被動態代理攔截到,而後經過網絡請求調用提供者.
一樣的,咱們在項目中配置的地址是zookeeper的地址.緣由同上兩個中間件原理一致
你會發現,中間件的簡單原理基本是同樣的.經過這個類比學習,你之後遇到其餘的中間件,哪怕是本身公司自研的中間件,他們的原理你也能迅速上手.
分析完原理以後,那咱們遇到了什麼問題呢?好比RocketMQ,咱們配置的是NameSever
的地址,那麼這個地址咱們能夠經過Nginx映射出來.這樣咱們就能夠訪問到NameSever
.可是Broker
的地址,是Rocket本身註冊上去的.咱們即便映射了192.168.X.XXX
.可是Broker
註冊地址的邏輯代碼裏面仍是會把192.168.Y.YYY
註冊上去.那麼咱們訪問的仍是192.168.Y.YYY
那麼咱們映射的這個192.168.X.XXX
就沒有做用.
那麼咱們是否是裝個逼秀一波操做,改源碼的邏輯,讓Broker
註冊的地址按照咱們映射的192.168.X.XXX
註冊上去呢?
我只想說,年輕人,你這個思想很危險啊!
編程講究的是開閉原則,再說,你肯定能駕馭得住的RocketMQ的源碼改動嗎?我都說了,遇到問題,先不要着急看源碼.先看官方文檔,再經過搜索引擎,若是都不能解決的.咱們再看源碼.我百度搜索第一條就是答案的我還看個毛線源碼!那麼咱們來看下官方文檔
人家這個說得就很清楚了,默認是註冊本地的ip地址上去,可是你能夠設置.因此咱們把本身的映射的ip地址配置上去就OK了.
RocketMQ的問題咱們經過官方文檔解決了.可是Dubbo的問題文檔沒有.搜索了有相似答案,可是依然沒有把原理講清楚.那麼咱們就直入源碼一探究竟(好吧,讓我裝個逼)
若是你以前就關注肥朝,一直有看過個人dubbo源碼解析系列,好比dubbo源碼解析-zookeeper建立節點
那麼你就能像我這種風通常的男子同樣迅速定位到源碼中獲取ip地址的源碼片斷.以下
這部分的邏輯是,先調用InetAddress.getLocalHost().getHostAddress()
,若是該方法返回一個合法地址,就直接認爲這個地址是本地的ip地址.不然會遍歷本地的全部網卡,並返回找到的第一個合法地址
1//這部分是jdk的api
2host = InetAddress.getLocalHost().getHostAddress();
既然是jdk的api,那麼要弄懂原理就好搞不少了.咱們直接看文檔註釋
1/**
2 * Returns the address of the local host. This is achieved by retrieving
3 * the name of the host from the system, then resolving that name into
4 * an {@code InetAddress}.
5 *
6 * <P>Note: The resolved address may be cached for a short period of time.
7 * </P>
8 *
9 * <p>If there is a security manager, its
10 * {@code checkConnect} method is called
11 * with the local host name and {@code -1}
12 * as its arguments to see if the operation is allowed.
13 * If the operation is not allowed, an InetAddress representing
14 * the loopback address is returned.
15 *
16 * @return the address of the local host.
17 *
18 * @exception UnknownHostException if the local host name could not
19 * be resolved into an address.
20 *
21 * @see SecurityManager#checkConnect
22 * @see java.net.InetAddress#getByName(java.lang.String)
23 */
從文檔的大概意思能夠看出,他獲取的ip地址,和hostName
有關.那麼這樣咱們就有了突破口.
咱們經過linux命令(uname -n
)查看機器的hostName,好比
而後編輯host文件
1vi /etc/hosts
好比設置
1192.168.1.102 testdemo
那麼咱們啓動dubbo服務
固然這樣我仍是不放心,咱們去zookeeper上看看節點
果真和咱們看到的是同樣的.
感謝你們一路以來的支持.後續的文章會在公衆號首發.公衆號名爲肥朝
.後續還會有更多的套路和奇巧淫技分享.公衆號等你來撩.