從軟件歷史看架構的未來:編程不再是精英們的遊戲

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"軟件歷史上有過兩次危機,有危機就有變革契機,第一次引出了“結構化編程”,第二次引出了“面向對象編程”,並直接導致軟件工程的誕生。今天我們且不用“第三次軟件危機”這樣的表述,但可以看到的是,從 2010 年左右開始興起的雲計算是程序的運行環境繼“大型計算機”轉變到“客戶端-服務器”之後的又一場鉅變。與前兩次軟件危機帶來的變革契機一樣,現有的許多軟件架構和開發方法,一定也會在以十年爲計數單位的時間段內逐漸被顛覆,而今天你我所談的雲原生、微服務等話題,僅僅是這次變革浪潮的開端。那麼,軟件開發的下一個核心矛盾將會是什麼?下一個時代的軟件架構會具備何種特徵?在今天由極客邦科技舉辦的ArchSummit全球架構師峯會 2021(深圳站)上,華爲 SaaS 首席軟件教練、《深入理解 Java 虛擬機》系列書籍作者周志明發表了主題演講《從軟件的歷史看架構的未來》,以下爲演講內容整理。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1972 年,"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Edsger_W._Dijkstra","title":"","type":null},"content":[{"type":"text","text":"Edsger Dijkstra"}]},{"type":"text","text":" 在爲圖靈獎頒授典禮所寫的"},{"type":"link","attrs":{"href":"https:\/\/www.cs.utexas.edu\/users\/EWD\/transcriptions\/EWD03xx\/EWD340.html","title":"","type":null},"content":[{"type":"text","text":"感言文章"}]},{"type":"text","text":"中說到:“在沒有計算機的時候,也就沒有編程問題;當我們有了簡單的計算機,編程就變成了小問題;而現在我們有了算力規模龐大的計算機,那編程就成爲一個同樣複雜的大問題了。”半個世紀前,Dijkstra 已經敏銳洞見了"},{"type":"text","marks":[{"type":"strong"}],"text":"機器算力的提升是編程方法發展的直接牽引,每當人類掌握了更強的算力,便按捺不住想去解決一些以前甚至都不敢去設想的新問題,由此引發軟件設計模式的重大變革。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"歷史上的軟件危機和契機"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"計算機剛誕生的年代,硬件規模還很小,甚至程序員僅憑大腦就足夠記住數據在幾 KB 內存中的佈局情況,理解每條指令在電路中的運行邏輯。此時的計算機儘管運算速度比人類快,但其內部卻沒有什麼人所不知道的事情;此時的軟件開發並沒有獨立的“架構”可言,軟件架構與硬件架構是直接物理對齊的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着計算機的快速發展,直接面向硬件進行的軟件開發很快觸碰到了瓶頸,人腦的生物侷限顯然無法跟上機器算力前進的步伐,當機器強大到世界上最聰明的人都無法爲它編寫出合適的程序了,那計算機科學還能繼續發展嗎?這便是歷史上第一次軟件危機的根源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一次軟件危機,同時也是"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Structured_programming","title":"","type":null},"content":[{"type":"text","text":"結構化編程"}]},{"type":"text","text":"發展的契機,結構化編程扭轉了當時直接面向全局數據、滿屏 Goto 語句書寫"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Spaghetti_code","title":"","type":null},"content":[{"type":"text","text":"麪條式代碼"}]},{"type":"text","text":"(Spaghetti Code)的編程風氣,強調可獨立編寫、可重複利用的子過程\/局部塊的重要性,讓軟件的每個局部都能夠設計專門的算法和數據結構,允許每一位程序員只關注自己所負責的部分,從而在整體上控制住了軟件開發的複雜度。此時,軟件的架構纔開始獨立於硬件物理架構而存在,軟件業開始出現把控全局設計的架構師與聚焦局部實現的程序員的角色分工。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將軟件從整體劃分成若干個局部,人類能夠以羣體配合來共同開發軟件,使得人與計算機又和諧共處了十餘年。不過,機器的算力膨脹仍然在持續,人類羣體的溝通協作能力卻終究有極限。人畢竟不是可複製的程序,每個人都有自己的理解與認知,如何讓各個模塊能準確地協同工作成了一場災難,這就是第二次軟件危機的根源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"《"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/The_Mythical_Man-Month","title":"","type":null},"content":[{"type":"text","text":"人月神話"}]},{"type":"text","text":"》中有一個幾乎每位程序員都聽過的案例:IBM 公司開發 OS\/360 系統的投入成本達到了美國“曼哈頓”原子彈計劃的 25%,共有 4000 多個模塊,約 100 萬條指令,超過 5000 人年,耗資數億美元,即使如此,結果還是延期交付,在交付使用後的系統中仍發現大量的缺陷。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"渡過第二次軟件危機的過程中,面向對象編程逐步取代了面向過程的結構化編程,成爲主流的程序設計思想。這次思想轉變宣告“追求最符合人類思維的視角來抽象問題”取代了“追求最符合機器運行特徵的算法與數據結構”成爲軟件架構的最高優先級,並一直持續沿用至今。這次危機還直接導致軟件工程的誕生,如何以系統性的、規範化的、可定量的方法去高質量地開發和維護軟件成爲一門獨立的科學。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"雲與分佈式逐漸成爲主流"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果說歷史上的第一、二次軟件危機分別是機器算力規模超過了人類個體的生理極限,超過了人類羣體的溝通極限的話。那麼在今天,在雲計算的時代,數據中心所能提供的算力其實已經逼近人類協作的工程極限。與此算力相符的程序規模,幾乎也到了無論採用何種工程措施去優化過程、無論採用什麼管理手段去提升質量,都仍然不可避免會出現意外與異常的程度。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家都相信只要軟件系統由大量人員共同研發,並使其分佈在雲中大量節點協同運行,隨着項目規模的增大、時間變長,就肯定會有人疏忽犯錯,會有代碼攜帶缺陷,會有電腦宕機崩潰,會有網絡堵塞中斷,總之,必然會受到墨菲定律的無情打擊。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"軟件架構要與硬件算力規模對齊,目前用來適配雲計算與分佈式的主流架構形式是微服務。微服務興起之時,曾湧現出各類文章去總結、讚美微服務帶來的種種好處,諸如簡化部署、邏輯拆分更清晰、便於技術異構、易於伸縮拓展應對更高的性能,等等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些當然都是重要優點,可是,如果不拘泥於特定場景的某個問題,以宏觀的角度來看,前面所列這種種好處都只算是“錦上添花”、是屬於讓系統“更好”的動因,肯定比不上如何確保系統的“生存”來得關鍵。在我看來,"},{"type":"text","marks":[{"type":"strong"}],"text":"從單體到微服務的最根本的推動力,是爲了方便某個服務能夠順利地“消亡”與“重生”,局部個體的生死更迭,是關係到整個系統能否可靠續存的關鍵因素。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉個例子,在很長的時間裏面,企業應用中採用單體架構的 Java 系統,其更新、升級都必須要有固定的停機計劃,必須在特定的時間窗口內才能按時開始,必須按時結束。如果出現了非計劃的宕機,那便是生產事故。但是軟件的缺陷不可能遵循停機計劃來“安排時間出錯”,爲了應對缺陷與變化,做到不停機地檢修,Java 曾經搞出了 OSGi 和 JVMTI Instrumentation 等複雜的 HotSwap 方案,以實現給奔跑中的汽車更換輪胎這種匪夷所思卻又無可奈何的需求。而在微服務架構的視角下,所謂系統檢修,充其量只是一次服務滾動更新而已,灰度部署新的程序版本,然後導流、測試、發佈即可。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"流水不腐,有老朽,有消亡,有重生,有更迭纔是生態運行的合理規律,如何採用不可靠的部件來構造出一個可靠的系統,是軟件架構適配雲與分佈式算力發展的關鍵所在。如果系統中局部能擁有獨立的生命週期,在整體架構上有物理隔離的設計,那麼即便採用了不可靠部件,在系統外觀察,整體上仍然有可能表現出穩定健壯的服務能力。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"從雲計算到雲不可知"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們繼續順着“軟件架構的演進由人與機器的矛盾所驅動,逐漸與算力規模對齊”這條線索,思考軟件開發的下一個核心矛盾將會是什麼?窺探下一個時代的軟件架構會具備何種特徵?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我認爲,軟件發展的下一個關鍵矛盾將會是算力規模超過人應掌握合理知識的極限。經過良好設計的分佈式系統,擁有局部的可再生性,確實能在整體上展現出可靠的服務能力。然而,“良好地設計”一個分佈式系統很不容易。今天無限火熱的雲原生、微服務、不可變基礎設施、彈性計算、服務網格、無服務器架構、高低零代碼等等,背後都能展開成一整套成體系的開發或者設計方法。"},{"type":"text","marks":[{"type":"strong"}],"text":"這些新的技術在爲人們解決了更復雜軟件問題的同時,也正在把編程這件事情本身的複雜度推向更高層次。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一名剛剛走出校園的大學生,要掌握計算機與程序執行的基本原理,要消化完所用編程語言的核心細節,要掌握領域中常用的類庫、框架和工具,要理解分佈式系統的服務彈性、容錯、限流等設計技巧,要接觸容器、雲原生、函數計算等運行架構層面的知識,耗費上十年時間都絲毫不奇怪。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在哲學裏,有人曾經嚴肅研討過“"},{"type":"link","attrs":{"href":"https:\/\/www.zhihu.com\/question\/351877512\/answer\/866449201","title":"","type":null},"content":[{"type":"text","text":"知識膨脹"}]},{"type":"text","text":"”的問題,說的是人類科學的前沿在不斷拓展,觸及前沿所需的基礎知識也不斷增加,是否會陷入後來者終其一生都無法攢下足夠基礎,導致人類知識陷入止步不前的危機之中。在計算機科學裏就更加現實了,知識膨脹直接表現爲從畢業到“"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/fhzjrzzmzvcee17rcrm0","title":"","type":null},"content":[{"type":"text","text":"35歲退休"}]},{"type":"text","text":"”(梗)之前,很多程序員恐怕都很難具備設計分佈式架構所需的全面知識。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"雲與分佈式時代,軟件知識看來又到了該“打個結”的時刻,要設法把那些重要但普適的知識標準化並下沉。"},{"type":"text","text":"好比今天除去少數專門的領域,大多數程序員已經不再需要關注寄存器、信號、中斷等與機器底層的細節,也不會太關注操作系統內存頁\/段、執行調度器、輸入輸出原理等操作系統底層的細節。等雲數據中心徹底成熟,成爲主流的程序部署運行環境後,雲與分佈式的複雜細節也同樣會被隱藏起來。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"未來軟件如何使用雲服務,現階段還很難有定論,但有跡象表明,軟件中的"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/DFX","title":"","type":null},"content":[{"type":"text","text":"非功能屬性"}]},{"type":"text","text":"會率先被外置出去,而不會繼續像現在這樣,在開發階段鐫刻定型於程序代碼之中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"軟件是以單體還是以分佈式運行,需要提供怎樣的 SLA,具體與哪些技術組件進行協作,通訊中是否要容錯限流等等,都不必在開發期就鎖定起來,也不必由業務開發人員去關注,他們只處理那些承載系統業務價值的功能屬性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這種外掛式的軟件架構風格,如同你要上戰場便穿上軍裝,要游泳便穿上泳衣,去舞會便穿上禮服,不同的裝備讓人能適應不同的場景。而那些“可穿戴”的裝備,都是由專業廠商設計,有質量保證,不需要每位編寫代碼的程序員都知道它們應該如何工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正在逐漸成熟的 Service Mesh 就展露出一些這方面的特徵。Sidecar 以流量劫持的方式,能夠爲程序間的網絡通訊額外附加上連接穩定性(如重試、熔斷)、安全性(如鑑權、雙向通訊加密)、可管理性和可觀測性,既不依賴人專門去編碼,也不依賴某款語言或者框架的預置能力。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不過,Service Mesh 僅僅能滿足與服務通訊能力相關的治理,而軟件設計所需的能力並不止通訊這一項,開發者要依賴多種提供不同能力的運行時來搭建軟件,譬如高級語言虛擬機提供執行能力、消息隊列提供 Pub\/Sub 通知能力、容器編排系統提供生命週期管理能力等等。開發者使用這些能力時,也面臨與通訊一樣的治理需求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/shardingsphere.apache.org\/","title":"","type":null},"content":[{"type":"text","text":"ShardingSphere"}]},{"type":"text","text":" 的作者張亮曾經"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/database-mesh-sharding-jdbc","title":"","type":null},"content":[{"type":"text","text":"在 InfoQ 撰文"}]},{"type":"text","text":",提出過 Database Mesh 的設想,把數據庫發現、訪問路由、數據分片、讀寫分離、負載均衡等特性從程序代碼中拿出去,也交給 Sidecar 來實現。既然 Service 和 Database 可以 Mesh 化,那 Cache Mesh、MessageQueue Mesh、Storage Mesh等自然都有了登場的理由。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"更進一步,分佈式中那些複雜卻有共性的處理技巧,如並行、併發、狀態、共識等等,是不是也可以從程序代碼中獨立出去,由 Sidecar 引導至合適的、不特定的部件中妥善處理?最後,一旦雲計算服務提供商的技術貨架中大多數部件和能力被 Mesh 抹掉了差異化特性,剩下都是一致的標準操作,那 Serverless 一直倡導的“後端即服務”(BaaS)便立刻有了無比廣泛的基礎。此時,"},{"type":"text","marks":[{"type":"strong"}],"text":"雲數據中心就彷彿是一部擁有無限算力的機器與一套有標準接口的操作系統,開發者無需關心程序在哪裏執行(FaaS),也不再關心程序有哪些依賴(BaaS)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面僅談概念恐怕有些抽象,筆者以“如何存儲一個 K\/V 值對”爲例,來看一下當前的編程與未來設想的編程方式會有什麼差別。下面這段代碼是現在隨處可見的大路貨,它具有稍後列舉的幾點問題:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"Set nodes = new LinkedHashSet();\nnodes.add(new HostAndPort(\"192.168.1.1\", 6379));\nnodes.add(new HostAndPort(\"192.168.1.2\", 6379));\nJedisPoolConfig config = new JedisPoolConfig();\nconfig.setMaxTotal(1);\nconfig.setMaxIdle(1);\ntry (Jedis jedis = new JedisCluster(nodes, config)) {\n String result = jedis.set(\"icyfenix\", \"{\\\"name\\\":\\\"zzm\\\", \\\"email\\\":\\\"[email protected]\\\"}\");\n return ok(result);\n} catch (Exception e) {\n log.error(\"Redis error:{}\", ExceptionTools.getExceptionStackTrace(e));\n return false;\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,這是一段操作 Redis 的代碼,意味着你需要了解 Redis 的知識,不說實現原理,起碼要知道它的 API 該如何使用,程序代碼也必須引入 Redis 的客戶端 SDK 作爲依賴項。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次,這是一段可運行的 Java 代碼,意味着你需要知道 Redis 的服務位置(如 Host 地址、端口等)、部署方式(如單點、集羣、分片情況等)、鏈接信息(如鑑權方式、密碼等),這些其實應該是 SRE 而不是 SDE 的職責。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,這是一段在生產環境容易受到挑戰的代碼,生產可能還需要考慮額外的非功能屬性:要不要啓用連接池?併發策略是 first-write-wins 還是 last-write-wins ?是否需要支持事務?數據能保證什麼級別的一致性?要批量操作該怎麼辦?假若這些非功能屬性都反映到代碼上,結果肯定要比現在看到的複雜上不少,其中有一些需求甚至僅憑應用代碼是無法解決的。譬如要支持事務,用 Redis 可以,用 Memcached\/Cassandra 就不行;要支持強一致性,用 Etcd\/ZooKeeper 可以,用 Redis 就不行。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上問題,在今天看來其實都算不上真正的問題,去寫程序就該懂得寫程序的知識,但是作爲一名業務開發人員,目的僅僅是想保存或者讀取一個 K\/V 值對而已,要用 Redis、Etcd、Memcached 或關係庫作爲存儲、要用哪個雲服務商提供的存儲服務、要滿足哪些非功能特性,這些本不該屬於操作意圖的一部分,都應該被隱藏起來。譬如下面這樣來完成 K\/V 值對的存儲和訪問:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"curl -X POST http:\/\/localhost:3500\/v1.0\/state\/users \\\n -H \"Content-Type: application\/json\" \\\n -d '[\n {\n \"key\": \"icyfenix\",\n \"value\": {\"name\":\"zzm\", \"email\":\"[email protected]\"}\n }\n ]'\n\ncurl http:\/\/localhost:3500\/v1.0\/state\/users\/icyfenix \\\n -H \"Content-Type: application\/json\"\n\n{\"name\":\"zzm\", \"email\":\"[email protected]\"}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至於爲什麼會存在“"},{"type":"link","attrs":{"href":"http:\/\/localhost:3500","title":"","type":null},"content":[{"type":"text","text":"http:\/\/localhost:3500"}]},{"type":"text","text":"”這樣的服務地址,後面連接的具體是什麼存儲服務,這些是 Sidecar 而不是業務開發人員需要關心的事情。不同產品與不同雲計算服務商之間的差異,被隱藏在相同的操作原語(Primitives)和代表服務標準含義的接口(如 HTTP URL)之下。這樣雲計算就自然而然地打破了目前各廠商之間和產品之間的隔閡,順利步入到"},{"type":"link","attrs":{"href":"https:\/\/www.avenga.com\/magazine\/cloud-agnostic-vs-cloud-native\/","title":"","type":null},"content":[{"type":"text","text":"雲不可知"}]},{"type":"text","text":"(Cloud Agnostic)的階段。這便是對雲計算與分佈式架構“打個結”的具體動作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然迄今爲止,上述設想距離現實還很遙遠,理論不夠成熟,能在生產環境中使用的多運行時框架仍處於十分早期階段。譬如上面用於演示的代碼是基於微軟的 "},{"type":"link","attrs":{"href":"https:\/\/dapr.io\/","title":"","type":null},"content":[{"type":"text","text":"DAPR"}]},{"type":"text","text":" 框架,它在上週纔剛剛進入 "},{"type":"link","attrs":{"href":"https:\/\/www.cncf.io\/","title":"","type":null},"content":[{"type":"text","text":"CNCF"}]},{"type":"text","text":" 孵化。對這個演示 DAPR 目前也僅僅能處理 K\/V 存儲,其它存儲類型(如更爲常用的關係庫)目前都還完全沒有考慮。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但我願意相信"},{"type":"text","marks":[{"type":"strong"}],"text":"這是未來架構演進的一個主要方向,必須把複雜的問題儘量關進籠子,由專業人員去看護,才能讓普通程序員更好參與軟件開發,甚至通過低\/零代碼工具的支持,讓那些沒有太多編程知識、卻有豐富領域知識的業務專家,也能夠獨立製造出優秀的軟件產品。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"軟件、架構與人"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一次軟件危機在 1950 年代末期初現端倪,結構化編程思想在 1970 年才被正式提出;第二次軟件危機(連同“軟件危機”這個概念)是在 1970 年"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/NATO_Software_Engineering_Conferences","title":"","type":null},"content":[{"type":"text","text":"北約 NATO 會議"}]},{"type":"text","text":"上被定義的,要一直到 1990 年代面向對象的設計方法成爲主流,以及 Scrum、XP 等軟件工程方法被提出後,這次危機纔算是畫上句號。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從 2010 年左右開始興起的雲計算是程序的運行環境繼“大型計算機”轉變到“客戶端-服務器”之後的"},{"type":"link","attrs":{"href":"https:\/\/zh.wikipedia.org\/wiki\/%E9%9B%B2%E7%AB%AF%E9%81%8B%E7%AE%97#%E6%B2%BF%E9%9D%A9","title":"","type":null},"content":[{"type":"text","text":"又一場鉅變"}]},{"type":"text","text":"。與前兩次軟件危機帶來的變革契機一樣,"},{"type":"text","marks":[{"type":"strong"}],"text":"現有的許多軟件架構和開發方法,一定也會在以十年計數單位的時間段內逐漸被顛覆,今天你我所談的雲原生、微服務等話題,僅僅是這次變革浪潮的開端。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與技術變革相伴的,是它對行業以及對程序員這個羣體的影響。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第一次軟件危機期間,世界上最聰明的科學家\/工程學家在開發軟件;第二次軟件危機期間,社會中高智商高學歷的精英羣體在開發軟件;雲與分佈式的時代,軟件開發者恐怕也不可避免會受到下一輪衝擊。"},{"type":"text","marks":[{"type":"strong"}],"text":"未來的軟件架構對普通程序員應該會是更友善更簡單的,但是對普通程序員友善與簡單的背後,預示着未來的信息技術行業很可能會出現“階級分層”的現象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於更先進的軟件架構已經允許更平庸的開發者也同樣能寫出可運行、可用於生產的軟件產品,同時又對精英開發者提出更多、更復雜的技術要求。長此以往,在開發者羣體中會出現比現在還要更顯著的"},{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Matthew_effect","title":"","type":null},"content":[{"type":"text","text":"馬太效應"}]},{"type":"text","text":",迫使開發者逐漸分層。從如今所有開發者都普遍被認爲是“高智商羣體”的狀態,轉變爲大部分工業化軟件生產工人加上小部分軟件設計專家的金字塔結構,就如同現在的建築工人與建築設計師的關係一般。今天我們經常自嘲的 CRUD Boy,隨着軟件產業日趨成熟,恐怕還會真的會成爲現實。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在本次分享中,我避免使用“第三次軟件危機”這樣有譁衆取寵嫌疑的表述,危機總是與契機同時出現,未來的軟件的一定是越來越貼近於普通平民百姓的軟件,但軟件的未來也一定有大量的挑戰與機會在等待着優秀的程序員與架構師去承擔。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章