從解決開發環境問題聊聊爲何要看源碼

前言

去年寫了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框架

從上面兩個圖你就能夠看出.在fastDFS中,Tracker Server就相似NameSever,Storage Server就相似Broker.原理基本是同樣的.一樣的,平時咱們項目中配置的地址實際上是Tracker Server的地址

類比Dubbo學習

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了.

Dubbo的問題

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上看看節點

圖片

果真和咱們看到的是同樣的.

圖片

寫在末尾

感謝你們一路以來的支持.後續的文章會在公衆號首發.公衆號名爲肥朝.後續還會有更多的套路和奇巧淫技分享.公衆號等你來撩.

相關文章
相關標籤/搜索