台中市北屯區第14期重劃區內,有一對黑翅鳶忙著築巢繁殖

台中市北屯區第14期重劃區內,有一對黑翅鳶忙著築巢繁殖,成為鳥友攝影的主角,不料,前天(8月31日)卻驚見中市政府委託的包商,跑到鳥巢附近修剪樹木與移除枯木,鳥友擔心黑翅鳶育雛受干擾,趕緊打電話請市府停工,勿讓黑翅鳶家庭受毀滅浩劫,對此,市府建設局長陳大田說,此區域暫緩施工,等繁殖期過後,再研擬後續處理之道。

拍鳥俱樂部會長黃蜀婷說,黑翅鳶是列為第二級珍貴稀有的保育猛禽鳥類,擅長抓老鼠,黑翅鳶是友善大地的小幫手,有「最美麗的猛禽」與「捕鼠神器」美譽。

她指出,中市14期重劃區內有一對黑翅鳶夫妻棲息,該繁殖期(春天至秋天)已育雛一次,但僅一隻雛鳥長大為亞成鳥,這對夫妻一邊育雛,又在原巢旁築第二個鳥巢,這幾天忙著交配,不料,鳥友回報,市府委託的工人在鳥巢附近施工,鳥友擔心黑翅鳶受干擾,甚而鳥巢被破壞,亞成鳥沒有長大的機會,或黑翅鳶放棄在第二鳥巢下蛋育雛,趕緊拜託中市政府暫緩施工。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※影響示波器測試準確度的五大因素

※無毒橡膠墊片哪裡買的到?

※飲用桶裝水到底安不安全? 破解錯誤迷思!

※十大封口機人氣排行榜-烘焙必備幫手!

封口機購物網-不怕你比價,就怕你買貴!

※買不起高檔茶葉,精緻包裝茶葉罐,也能撐場面!

※(全省)堆高機租賃保養一覽表

台灣海洋大學珊瑚團隊主持人識名信也採集東北角珊瑚

台灣海洋大學珊瑚團隊主持人識名信也採集東北角珊瑚,在新北市海洋資源復育園區研究與種植,以因應極端氣候可能造成珊瑚大量死亡,作為海洋復育珊瑚、科學開發新藥材的能量。

海洋委員會今年補助新北市執行海域珊瑚海洋教育推廣計畫,新北市漁業及漁港事業管理處今天(31日)表示,珊瑚礁是海洋中生物種類歧異度最高的生態系,盼透過「珊瑚小學堂」海洋教育課程,讓市民體會海洋保育的重要性。

國立台灣海洋大學副教授識名信也與貢寮海洋資源復育園區合作,負責研究及復育珊瑚,實驗室擁有培養珊瑚室內池、室外池及海底池,部分培養的珊瑚來源是鄰近的九孔鮑養殖戶提供。

珊瑚小學堂讓民眾近距離接觸東北角常見的珊瑚物種,也利用珊瑚的特性讓民眾動手「種珊瑚」,作為將來復育與研究,開發新藥物的材料,減少野外採集數量。海大與市府合作在海洋資源復育園區設立「水生生物研究暨保育中心」,開發東北角暨北海岸重要經濟性物種繁養殖技術。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

無塵擦拭紙各大品牌廠商販售比價網!

※如何知道自已的電腦cpu支不支持AVX指令集?

※如何正確使用飲水機?

※攻戰消費者第一視覺,包裝設計很重要!

滑鼠墊適用各種文宣活動廣告曝光,專業客製服務

封口機購物網-不怕你比價,就怕你買貴!

花蓮林田山林業文化園區是台灣現存最完整、具特色的伐木基地

花蓮林田山林業文化園區是台灣現存最完整、具特色的伐木基地,林務局計畫爭取新台幣10億元經費,打造「林業文化廊道」,獲農委會主委陳吉仲、民進黨立委蕭美琴肯定。

花蓮林管處長楊瑞芬接受中央社記者採訪表示,林業文化資源保存與整體再發展中長程計畫,預計四年內投入新台幣10億元重整園區設備,包括修復1234公尺舊有軌道,設置電動遊園列車及72棟宿舍修復。

楊瑞芬指出,從交通、產業、經營等面向發展,包括自行車路網、軌道修復,到在地木創藝術家駐村、林業聚落體驗等,再現林田山繁榮景象,預計今年10月向行政院提出計畫。

蕭美琴表示,林田山有豐富的歷史文化內涵,深具發展潛力,也獲得總統蔡英文肯定。花蓮林管處接手後,轉型為林業文化園區,聚落裡的辦公廳舍、生活設施、員工宿舍、國小校舍等日式建築及林業文化多完整保留,獲縣文化局登錄為聚落建築群。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

無塵擦拭紙各大品牌廠商販售比價網!

※如何正確使用飲水機?

※如何知道自已的電腦cpu支不支持AVX指令集?

※掌握產品行銷策略,帶你認識商品包裝設計基本要素

商業用玻璃煎台不必開大火也能迅速導熱

※選用哪種桶裝水,外宿露營超方便?

中油公司大林煉油廠觸媒裂解製程燃燒塔今天(30日)排放濃煙

中油公司大林煉油廠觸媒裂解製程燃燒塔今天(30日)排放濃煙,高雄市政府環保局派人稽查採樣,燃燒塔排放大量濃煙粒狀污染物,時間約15分鐘,當場開單告發。

位於高雄臨海工業區的中油公司大林廠燃燒塔於下午近2時排放大量濃煙,環保局據報派人稽查採樣,廠方表示是觸媒裂解製程因去丁烷塔出口管線阻塞,導致廢氣燃燒塔緊急排放。

高雄市環保局環境稽查科表示,經派人稽查確認是因管線內氣體壓力過大,造成安全閥跳車,製程氣體轉至廢氣燃燒塔燃燒,導致排放大量濃煙粒狀污染物。

對於燃燒塔緊急排放廢氣燃燒並排放濃煙15分鐘這部分,環保局表示,將先依違反空污法32條第一項第一款告發,並依污染情節裁罰新台幣60萬元。高雄市環保局長袁中新表示,中油大林廠已設置多年,應加強檢修及平時維護保養,避免排放或逸散空氣污染物於空氣中,增加高雄地區的污染負荷。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

飲水機皆有含淨水功能嗎?

※各種升降平台款式?

※飲用桶裝水到底安不安全? 破解錯誤迷思!

※十大封口機人氣排行榜-烘焙必備幫手!

※高價位跟低價位的示波器又有何差異?

※高效率洗滌塔活性碳設備有哪些?

新北環保局推出免費到府節電診斷服務,還有30個免費診斷名額

新北環保局推出免費到府節電診斷服務,還有30個免費診斷名額,專業節電團隊會整合性診斷社區的電力、空調、照明系統、建築物綠化等,提出整體性節電建議,有社區一年省下10幾萬元電費。

台北市環保局去年也開始規劃「社區節電輔導」,主要篩選一些供電或設備較老舊的公寓大廈社區,派遣節電專家前往免費輔導,但受限資源和人力,目前預計每年篩選十處大樓社區陸續辦理,之後會視情況評估擴大辦理與否。

新北市低碳社區發展中心主任鄧筱光說,專業節電醫師團隊會診斷社區的電力、空調、照明系統、水資源管理、資源回收再利用、建築物綠化及隔熱等整合性診斷,協助社區找出可以節能減碳的空間,並提供診斷報告書。

鄧筱光指出,報告書建議內容包括社區用電的契約容量調整、停車場照明汰換、機電設施更換等,同時也提供新北各局處的補助方案,另也列舉更換時所需的經費、成效,預計幾年後能夠回本,讓社區能夠詳細參考,再決定如何節電。

本站聲明:網站內容來源於https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※客製專屬滑鼠墊、可愛造型L夾L型資料夾、透明證件套、手提袋,專業印刷設計廠商!  

示波器鮮為人知的使用技巧?

※掌握產品行銷策略,帶你認識商品包裝設計基本要素

※買不起高檔茶葉,精緻包裝茶葉罐,也能撐場面!

※各種升降平台款式?

※高效率洗滌塔活性碳設備有哪些?

一起玩轉微服務(12)——揭密starter

介紹

Spring Boot的starter主要用來簡化依賴用的,對於企業級開發中的與第三方的集成,可以通過一段簡單的配置來完成,這樣開發人員無需再對包依賴的問題頭疼。Spring Boot為我們提供了簡化企業級開發的絕大多數場景的starter pom,只需要指定需要配置的starter,Spring Boot會自動為我們提供配置好的bean。

通常流程

通常我們要搭建一個基於Spring的Web應用,我們需要做以下一些工作:

pom文件中引入相關jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java 等等相關jar …

配置web.xml,Listener配置、Filter配置、Servlet配置、log4j配置、error配置 …

配置數據庫連接、配置spring事務

配置視圖解析器

開啟註解、自動掃描功能

配置完成後部署tomcat、啟動調試

……

花在搭建一個初始項目,可能一個小時就過去了或者半天就過了,但是用了SpringBoot之後一切都會變得非常便捷。

常用的starter

Spring Boot常用的starter(啟動器)包括:

  • Spring-boot-starter-logging :使用 Spring Boot 默認的日誌框架 Logback。
  • Spring-boot-starter-log4j :添加 Log4j 的支持。
  • Spring-boot-starter-web :支持 Web 應用開發,包含 Tomcat 和 Spring-mvc。
  • Spring-boot-starter-tomcat :使用 Spring Boot 默認的 Tomcat 作為應用服務器。
  • Spring-boot-starter-jetty :使用 Jetty 而不是默認的 Tomcat 作為應用服務器。
  • Spring-boot-starter-test :包含常用的測試所需的依賴,如 Junit、Hamcrest、Mockito 和 Spring-test 等。
  • Spring-boot-starter-AOP :包含 Spring-AOP 和 AspectJ 來支持面向切面編程(AOP)。
  • Spring-boot-starter-security :包含 Spring-security。
  • Spring-boot-starter-jdbc :支持使用 JDBC 訪問數據庫。
  • Spring-boot-starter-redis :支持使用 Redis。
  • Spring-boot-starter-data-mongodb :包含 Spring-data-mongodb 來支持 MongoDB。
  • Spring-boot-starter-data-jpa :包含 Spring-data-jpa、Spring-orm 和 Hibernate 來支持 JPA。
  • Spring-boot-starter-amqp :通過 Spring-rabbit 支持 AMQP。
  • Spring-boot-starter-actuator : 添加適用於生產環境的功能,如性能指標和監測等功能。

當然,如果有必要,也可以定製自己的starter。

起步依賴

在我們的pom文件裏面引入以下jar:

spring-boot-starter-web包自動幫我們引入了web模塊開發需要的相關jar包。

 

mybatis-spring-boot-starter幫我們引入了dao開發相關的jar包。 spring-boot-starter-xxx是官方提供的starter,xxx-spring-boot-starter是第三方提供的starter。

截圖看一下我們的mybatis-spring-boot-starter

可以看出mybatis-spring-boot-starter並沒有任何源碼,只有一個pom文件,它的作用就是幫我們引入其它jar。

 

得益於starter的作用,使用SpringBoot確實方便,但對剛剛上手SpringBoot的人來說,可能只知道配置屬性是在application.xml或application.yml中添加,但他們各自的屬性都有哪些,具體怎麼配置,卻無從下手。這裏先解決SpringBoot-starter中各屬性的配置問題。

Mybatis的配置是怎麼生效的?查看示例工程的pom依賴:

注意到mybatis-spring-boot-starter幫我們自動依賴了Mybatis所需jar包,其中有一個負責自動配置的mybatis-spring-boot-autoconfigure.jar,緊接着打開此jar,如下:

META-INF/spring-configuration-metadata.json中便是Mybatis在SpringBoot中的所有配置屬性和介紹。

SpringBoot-starter自動配置bean

現在已得知jar包是怎麼樣自動依賴進來,以及他們的配置屬性,那麼接下來該考慮Mybatis所需的bean(如必需的sqlSessionFactory、sqlSessionTemplate等)是如何被自動加載的?

理所應當地,我們繼續去查看mybatis-spring-boot-autoconfigure.jar,注意到裏面有一個自動配置的類MybatisAutoConfiguration:

(1)@Configuration:被掛上@Configuration註解,表明它是一個配置類,作用等同於xml配置,裏面有被@Bean註解的方法,也等同於xml配置的各種。

(2)@ConditionalOnClass/@ConditionalOnBean:自動配置條件註解,用於在某一部分配置中,將另一模塊部分的配置自動加載進來,因為隨着系統越來越大,配置內容越來越多,我們應當將Mybatis的配置放在一處,將log4j的配置放在一處,將SpringBoot自身的配置放在一處,當他們需要互相依賴時,可通過這類註解進行自動配置,如下:

@ConditionalOnClass @ConditionalOnMissingClass
@ConditionalOnBean @ConditionalOnMissingBean
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication @ConditionalOnNotWebApplication
@ConditionalOnExpression
 
@AutoConfigureAfter @AutoConfigureBefore @AutoConfigureOrder(指定順序)
 

(3)@EnableConfigurationProperties:啟用對@ConfigurationProperties註解的bean的支持,這裏對應了配置屬性類MybatisProperties,它裏面定義了Mybatis的所有配置。

(4)@AutoConfigureAfter:應在其他指定的自動配置類之後應用自動配置。即org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration被自動配置后,才會接着自動配置MybatisAutoConfiguration。這裏也解釋了為什麼我們在application.xml中只配置了數據源,而沒有配置Mybatis,但是Mybatis可以正常查庫的原因,就是因為它們配置之間的依賴關係。

到這裏,差不多明白了starter自動配置bean的方式,但是如若再去深究,各種starter的bean是如何被自動加載的,猜想會不會是項目啟動后,SpringBoot自動掃描裏面所有的jar包,再去掃描所有的類,從而將各個bean放置IOC容器中。從結果來看,肯定是SpringBoot在啟動時確確實實地自動加載了數據源和Mybatis相關的bean,不然他們無法正常工作。

回想在我們啟動示例工程時,SpringBoot會自動掃描啟動類所在包下的所有類,而如果還去掃描所有的jar包的話,又是具體怎麼做到的?不妨從入口類調試一把,在SpringApplication.run(DemoApplication.class, args)打斷點,一直追蹤到getSpringFactoriesInstances這塊:

查看SpringFactoriesLoader.loadFactoryNames的方法註釋:

 

使用給定的類加載器從META-INF / spring.factories加載給定類型的工廠實現的完全限定類名。

這裏的spring.factories剛好也存在於mybatis-spring-boot-autoconfigure.jar中,

繼續調試,進入SpringFactoriesLoader.loadFactoryNames,

這裏用類加載器得到工程中所有jar包中的META-INF/spring.factories文件資源,進而通過此文件得到了一些包括自動配置相關的類的集合,有各種工廠類、監聽器、處理器、過濾器、初始化器等等,如下:

最後的org.springframework.boot.autoconfigure.EnableAutoConfiguration集合中當然包括了org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration和org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration。接着必然是將實例化的各個bean放進IOC容器中。

至此我們便明白了SpringBoot是如何自動配置starter裏面的bean的。

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

那些年,我們用過的服務器軟件

引言

看過這部電影的人都老了。。。

很多人都知道我是一名後端開發底層小碼農,平時打交道最多的就是服務器,而關於服務器,又有一堆名詞,看起來好像是一個意思,仔細想想又好像不對。

不信?

先放三個名詞「Web 服務器」、「HTTP 服務器」、「應用服務器」。這三種服務器有誰能現在立刻馬上區分開么。

反正我是區分不開。這個問題要是扔到一堆程序員中間,指不定還能引發一場菜雞爭奪戰。

雖然我不會,不會可以度娘啊,希望經常看我文章同學可以有我這種敢於承認自己菜的精神,沒啥好丟人的,不會可以學,學完了下次就會了,總比不會裝會死鴨子嘴硬,下次還不會要強。

經過我一翻度娘 + 整理后,基本上這三個名詞解釋有了:

「Web 服務器」它一般指的是網站服務器,可以向瀏覽器( PC 端或者移動端)等 Web 客戶端提供服務,供請求數據或者下載數據。

而由於 Web 服務器主要支持的協議就是 HTTP 或者 HTTPS ,所以通常情況下 Web 服務器和 HTTP 服務器是等同的,這兩種服務器之間是可以畫上等號的。

而應用服務器是一個很大的概念,微軟對它的定義是「我們把應用程序服務器定義為:作為服務器執行共享業務應用程序的底層的系統軟件。 就像文件服務器為很多用戶提供文件一樣,應用程序服務器讓多個用戶可以同時使用應用程序(通常是客戶創建的應用程序)」。

講的通俗一點就是一種特定應用的承載容器,一般來講,它需要有運行時環境的支持,比如說在 Java 領域,比較常用的應用服務器 Tomcat ,它就必須要 Java 的環境支持。

站在我的角度上,一名 Java 底層碼農從業人員的角度上來看,「Web 服務器」、「HTTP 服務器」、「應用服務器」之間的界限是非常模糊的,因為同樣一個 Tomcat 服務器,我叫它「Web 服務器」或者「HTTP 服務器」沒有問題,叫它「應用服務器」也沒有半毛錢問題。

常見的「Web 服務器」有 Nginx 、 Apache 、 IIS (這個做 .Net 的同學應該不陌生),常見的「應用服務器」軟件包括 WebLogic、JBoss,前者更輕量級,後者更重量級。

靜態服務和動態服務

接下來科普另一個概念:「靜態服務」和「動態服務」。

「靜態服務」返回的是一些靜態資源,比如圖片、HTML 、 CSS 、 JavaScript 等資源,這些靜態資源有一個顯著的特點是在我們的電腦上,只要路徑寫對了,可以在瀏覽器裏面直接訪問。

比如我在電腦上新建一個文件,把後綴改成 html ,裏面使用 html 隨便寫點內容:

<html>
    <h1>Hello World!</h1>
</html>

靜態服務就是每個人訪問,得到的內容都是一樣的,而動態服務就比較牛逼了,能做到每個人訪問,得到的內容都是不一樣的。

最直接的例子就是經常用的淘寶京東這些網站,登錄以後,訪問自己賬號的個人中心,肯定每個人得到的結果都是不一樣的結果。

還有就是我的博客,最開始我的博客是使用 Hexo 搭建的靜態博客,託管在騰訊雲的文件服務上,後來開了一台雲服務器,就換成了使用 WordPress 構建的動態博客。

Nginx

Nginx 是一款輕量級的 Web 服務器 / 反向代理服務器及电子郵件( IMAP / POP3 )代理服務器。

不查還真不知道,原來 Nginx 還提供了 IMAP / POP3 / SMTP 服務,設置過郵箱客戶端的同學對這三個名詞應該不陌生。

關於 Nginx ,比較令人遺憾的一件事是,它的作者伊戈爾·賽索耶夫進了監獄。

Nginx 的特點是佔有內存少,併發能力強,在同類型的網頁服務器中表現較好,國內比較有名的公司,比如說百度、京東、新浪、網易、騰訊、淘寶等都在使用。

Nginx 現在用途最多的應該是作為反向代理服務器在使用,因為它的特性穩定、佔用系統資源少、併發能力強,一般都直接放在直面用戶的最外層應對用戶流量。

用戶的訪問請求先落到 Nginx 上,由 Nginx 進行代理轉發,負載均衡到後續的 Tomcat 應用服務器上,盡可能的提升系統的穩定性。

至於 Nginx 如何複雜均衡到後面的應用服務器上,這就是另一個問題了, Nginx 有很多種的負載均衡方案,這裏我就不展開介紹了。

Nginx 是一個典型的靜態服務,把圖片等內容放在 Nginx 上,可以通過固定的鏈接直接訪問。

不過現在通過 Lua 的加持,我們也可以在 Nginx 做一些動態服務才能做的事情,這就是大名鼎鼎的 OpenResty 。

至於 Nginx 安裝或者是 OpenResty 的安裝以及簡單的使用,大家可以訪問各自的官網查看,我就不演示介紹了(反正都不難)。

Tomcat

在我的碼農生涯中,使用最多的莫過於 Tomcat ,沒有之一。

Tomcat 啟動成功的話,訪問它的首頁,正常情況下是能看到一隻貓的,雖然這隻貓長得實在是有點抽象,但人家確實是只貓。

Tomcat 是 Apache 軟件基金會( Apache Software Foundation )的 Jakarta 項目中的一個核心項目,由 Apache 、 Sun 和其他一些公司及個人共同開發而成。

Tomcat 服務器是一個免費的開放源代碼的 Web 應用服務器,這也是為什麼它可以風靡全球的重要原因。

由於這個項目有了 Sun 公司的參与和支持,所以 Tomcat 一般都會支持最新版的 Servlet 和 JSP 規範。這也是為什麼 Java 初學者接觸到的第一個 Web 服務總會是 Tomcat 。

但是 Tomcat 並未支持 EJB 和 JMS ,所以說 Tomcat 是一款輕量級的 Web 容器。

GlassFish

Sun 公司為 Java 提供了商業兼容的 Web 容器: Glassfish ,不過說實話,我沒怎麼用過這個容器,這個 Web 容器僅存在於我上大學的時候的課本上以及課後大作業上。

GlassFish 達到產品級質量,可免費用於開發、部署和重新分發。開發者可以免費獲得源代碼,還可以對代碼進行更改。

Glassfish 既是 EJB 容器也是 WEB 容器,它支持最新版的 Java EE 標準。

而剛才前面介紹的 Tomcat 則僅僅只是一個 Web 容器。

Jboss

Jboss 是一個基於 Java EE 的開放源代碼的應用服務器。 JBoss 代碼遵循 LGPL 許可,可以在任何商業應用中免費使用。

Jboss 和上面的 Glassfish 一樣,同樣是企業級的 Web 容器,並且在 2004 年 6 月, JBoss 公司宣布, JBoss 應用服務器通過了 Sun 公司的 J2EE 認證后,一直在緊跟最新的 J2EE 規範,而且在某些技術領域引領 J2EE 規範的開發。

因此,無論在商業領域,還是在開源社區, JBoss 成為了第一個通過 J2EE 1.4 認證的主流應用服務器。 JBoss 應用服務器已經真正發展成企業級應用服務器。

之後好景不長,在 2006 年, JBoss 被 Red Hat 以三億五千萬美金併購。

之後在 2019 年,也就是去年, Red Hat 為 JBoss Application Server 換了一個新的名字,即: WildFly 。

因為 JBoss 本身是開源免費的,而 Red Hat 的企業產品 JBoss EAP 是一個收費產品,Red Hat 為了使這兩個產品差異化,避免用戶混淆,而進行更名。

JBoss 版本:

  • 社區版:JBoss AS(Application Server) -> WildFly
  • 企業版:JBoss EAP(Enterprise Application Server)

JBoss 核心服務不包括支持 servlet / JSP 的 WEB 容器,一般與 Tomcat 綁定使用, JBoss 的 Web 容器使用的是 Tomcat 。

Apache

如果不是 IT 行業,如果說起來 Apache ,是不是大多數人想到的是這個東西:

不過顯然我要說的不是這個,而是這個小羽毛:

說起來慚愧,我在剛入門的很長一段時間中,一直以為 Apache 就是 Tomcat , 傻傻分不清楚。

後來接觸到 PHP 以後,才知道他們倆完全不同, Logo 就不同(這不是廢話)。

Apache 一般是指 Apache HTTP Server,是 Apache 軟件基金會(和 Tomcat 同屬一家基金會,並且 Apache 服務和 Apache 基金會名字都一樣,新人能分清才見鬼了)下的一個網頁服務器軟件。

由於其跨平台和安全性,被廣泛使用,是最流行的 Web 服務器軟件之一。它快速、可靠並且可通過簡單的 API 擴展。

我現在的博客站使用的就是 Apache 的服務,當時搞 WordPress 的時候着實坑了我一把,完全沒想到一個 PHP 環境這麼難搞,後來在網上找問題的搜索的時候才知道有 LAMP 這麼個東西。

  • Linux,操作系統。
  • Apache,網頁服務器。
  • MySQL,數據庫管理系統(或者數據庫服務器)。
  • PHP 、 Perl 或 Python,腳本語言。

不過還可以使用 Nginx 替換 Apache ,這個新的組合叫 LNMP 。

Jetty

Jetty 和 Tomcat 有很多相似之處,比如說可以為 JSP 和 Servlet 提供運行時環境。Jetty 是 Java 語言編寫的,它的 API 以一組 JAR 包的形式發布。

相比較 Tomcat 而言, Jetty 更加的輕量級,因為 Tomcat 除了遵循 Servlet 規範以外,自身還擴展了大量 Java EE 特性以滿足企業級應用的需求。

但對於大量普通的互聯網應用而言,並不需要用到 Tomcat 其他高級特性,所以在這種情況下,使用 Tomcat 是很浪費資源的。

而這時換成 Jetty ,每個應用服務器省下那幾 MB 內存,對於大的分佈式環境則是節省大量資源。

Jetty 可以同時處理大量鏈接並且長時間的保持這些鏈接,例如,一些 Web 聊天應用非常適合用 Jetty 服務器。

Jetty 的架構比較簡單,它有一個基本數據模型,這個數據模型就是 Handler,所有可以被擴展的組件都可以作為一個 Handler,添加到 Server 中,Jetty 就是幫我們管理這些 Handler 的。

Resin

最後一個放出來的是 Resin ,不知道有多少人聽說過這個 Web 容器。

Resin 是 CAUCHO 公司的產品,也是一個 Web 容器,對 Servlet / JSP 提供了良好的支持,性能也比較優良, Resin 自身採用 JAVA 語言開發。

基於百度百科的介紹是說 Resin 是一個非常流行的 Web 容器。

請恕我直言,這個容器真的這麼流行么,如果我不是因為維護一個公司的老系統,還真不知道還有這麼個 Web 容器。

可能 Resin 流行的年代比較久遠了,從我入行以後就不流行了。

其他

再說幾個只聽過沒接觸過的容器:

  • Undertow: JFinal 框架的默認容器切換成了 Undertow 。
  • WebLogic: 甲骨文出品,這個我沒接觸過,不過聽朋友講用這個大多數都是銀行,據說買一買挺貴的。
  • WebSphere: IBM 出品,這個和上面那個 WebLogic 一樣,只聽說過銀行在用。

JFinal 是基於 Java 語言的極速 WEB + ORM 框架,其核心設計目標是開發迅速、代碼量少、學習簡單、功能強大、輕量級、易擴展、Restful。用於一些小項目還是很合適的。

WebLogic 和 WebSphere 一看出品方都挺 NB 的,據說還有後台界面可以操作使用,發布程序都是點鼠標完成的。

不過現在發布程序大多數都開始用 Jenkins 了,其實也方便了很多,包括很多公司可能都上線了 DevOps 系統,程序發布只會越來越簡單。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

重學 Java 設計模式:實戰迭代器模式「模擬公司組織架構樹結構關係,深度迭代遍歷人員信息輸出場景」

作者:小傅哥
博客:https://bugstack.cn – 原創系列專題文章

沉澱、分享、成長,讓自己和他人都能有所收穫!

一、前言

相信相信的力量!

從懵懂的少年,到拿起鍵盤,可以寫一個HelloWorld。多數人在這並不會感覺有多難,也不會認為做不出來。因為這樣的例子,有老師的指導、有書本的例子、有前人的經驗。但隨着你的開發時間越來越長,要解決更複雜的問題或者技術創新,因此在網上搜了幾天幾夜都沒有答案,這個時候是否想過放棄,還是一直堅持不斷的嘗試一點點完成自己心裏要的結果。往往這種沒有前車之鑒需要自己解決問題的時候,可能真的會折磨到要崩潰,但你要願意執着、願意倔強,願意選擇相信相信的力量,就一定能解決。哪怕解決不了,也可以在這條路上摸索出其他更多的收穫,為後續前進的道路填充好墊腳石。

時間緊是寫垃圾代碼的理由?

擰螺絲?Ctrl+C、Ctrl+V?貼膏藥一樣寫代碼?沒有辦法,沒有時間,往往真的是借口,胸中沒用筆墨,才只能湊合。難道一定是好好寫代碼就浪費時間,拼湊CRUD就快嗎,根本不可能的。因為不會,沒用實操過,很少架構出全場景的設計,才很難寫出優良的代碼。多增強自身的編碼(武術)修為,在各種編碼場景中讓自己變得老練,才好應對緊急情況下的需求開發和人員安排。就像韓信一樣有謀有略,才能執掌百萬雄兵。

不要只是做個工具人!

因為日常的編寫簡單業務需求,導致自己像個工具人一樣,日久天長的也就很少去深入學習更多技術棧。看見有工具、有組件、有框架,拿來就用用,反正沒什麼體量也不會出什麼問題。但如果你想要更多的收入,哪怕是重複的造輪子,你也要去嘗試造一個,就算不用到生產,自己玩玩總可以吧。有些事情只有自己經歷過,才能有最深的感觸,參与過實踐過,才好總結點評學習。

二、開發環境

  1. JDK 1.8
  2. Idea + Maven
  3. 涉及工程一個,可以通過關注公眾號bugstack蟲洞棧,回復源碼下載獲取(打開獲取的鏈接,找到序號18)
工程 描述
itstack-demo-design-15-00 開發樹形組織架構關係迭代器

三、迭代器模式介紹

迭代器模式,常見的就是我們日常使用的iterator遍歷。雖然這個設計模式在我們的實際業務開發中的場景並不多,但卻幾乎每天都要使用jdk為我們提供的list集合遍歷。另外增強的for循環雖然是循環輸出數據,但是他不是迭代器模式。迭代器模式的特點是實現Iterable接口,通過next的方式獲取集合元素,同時具備對元素的刪除等操作。而增強的for循環是不可以的。

這種設計模式的優點是可以讓我們以相同的方式,遍歷不同的數據結構元素,這些數據結構包括;數組鏈表等,而用戶在使用遍歷的時候並不需要去關心每一種數據結構的遍歷處理邏輯,從讓使用變得統一易用。

四、案例場景模擬

在本案例中我們模擬迭代遍歷輸出公司中樹形結構的組織架構關係中僱員列表

大部分公司的組織架構都是金字塔結構,也就這種樹形結構,分為一級、二級、三級等部門,每個組織部門由僱員填充,最終體現出一個整體的樹形組織架構關係。

一般我們常用的遍歷就是jdk默認提供的方法,對list集合遍歷。但是對於這樣的偏業務特性較大的樹形結構,如果需要使用到遍歷,那麼就可以自己來實現。接下來我們會把這個組織層次關係通過樹形數據結構來實現,並完成迭代器功能。

五、迭代器模式遍歷組織結構

在實現迭代器模式之前可以先閱讀下javalist方法關於iterator的實現部分,幾乎所有的迭代器開發都會按照這個模式來實現,這個模式主要分為以下幾塊;

  1. Collection,集合方法部分用於對自定義的數據結構添加通用方法;addremoveiterator等核心方法。
  2. Iterable,提供獲取迭代器,這個接口類會被Collection繼承。
  3. Iterator,提供了兩個方法的定義;hasNextnext,會在具體的數據結構中寫實現方式。

除了這樣通用的迭代器實現方式外,我們的組織關係結構樹,是由節點和節點間的關係鏈構成,所以會比上述的內容多一些入參。

1. 工程結構

itstack-demo-design-15-02
└── src
    ├── main
    │   └── java
    │       └── org.itstack.demo.design
    │           ├── group
    │           │	├── Employee.java
    │           │	├── GroupStructure.java
    │           │	└── Link.java
    │           └──  lang
    │            	├── Collection.java
    │            	├── Iterable.java
    │            	└── Iterator.java
    └── test
        └── java
            └── org.itstack.demo.design.test
                └── ApiTest.java

迭代器模式模型結構

  • 以上是我們工程類圖的模型結構,左側是對迭代器的定義,右側是在數據結構中實現迭代器功能。
  • 關於左側部分的實現與jdk中的方式是一樣的,所以在學習的過程中可以互相參考,也可以自己擴展學習。
  • 另外這個遍歷方式一個樹形結構的深度遍歷,為了可以更加讓學習的小夥伴容易理解,這裏我實現了一種比較簡單的樹形結構深度遍歷方式。後續讀者也可以把遍歷擴展為橫向遍歷也就是寬度遍歷。

2. 代碼實現

2.1 僱員實體類

/**
 * 僱員
 */
public class Employee {

    private String uId;   // ID
    private String name;  // 姓名
    private String desc;  // 備註
    
    // ...get/set
}
  • 這是一個簡單的僱員類,也就是公司員工的信息類,包括必要的信息;id、姓名、備註。

2.2 樹節點鏈路

/**
 * 樹節點鏈路
 */
public class Link {

    private String fromId; // 僱員ID
    private String toId;   // 僱員ID    
    
    // ...get/set
}
  • 這個類用於描述結構樹中的各個節點之間的關係鏈,也就是A to BB to CB to D,以此描述出一套完整的樹組織結構。

2.3 迭代器定義

public interface Iterator<E> {

    boolean hasNext();

    E next();
    
}
  • 這裏的這個類和javajdk中提供的是一樣的,這樣也方面後續讀者可以對照listIterator進行源碼學習。
  • 方法描述;hasNext,判斷是否有下一個元素、next,獲取下一個元素。這個在list的遍歷中是經常用到的。

2.4 可迭代接口定義

public interface Iterable<E> {

    Iterator<E> iterator();

}
  • 這個接口中提供了上面迭代器的實現Iterator的獲取,也就是後續在自己的數據結構中需要實現迭代器的功能並交給Iterable,由此讓外部調用方進行獲取使用。

2.5 集合功能接口定義

public interface Collection<E, L> extends Iterable<E> {

    boolean add(E e);

    boolean remove(E e);

    boolean addLink(String key, L l);

    boolean removeLink(String key);

    Iterator<E> iterator();

}
  • 這裏我們定義集合操作接口;Collection,同時繼承了另外一個接口Iterable的方法iterator()。這樣後續誰來實現這個接口,就需要實現上述定義的一些基本功能;添加元素刪除元素遍歷
  • 同時你可能注意到這裏定義了兩個泛型<E, L>,因為我們的數據結構一個是用於添加元素,另外一個是用於添加樹節點的鏈路關係。

2.6 (核心)迭代器功能實現

public class GroupStructure implements Collection<Employee, Link> {

    private String groupId;                                                 // 組織ID,也是一個組織鏈的頭部ID
    private String groupName;                                               // 組織名稱
    private Map<String, Employee> employeeMap = new ConcurrentHashMap<String, Employee>();  // 僱員列表
    private Map<String, List<Link>> linkMap = new ConcurrentHashMap<String, List<Link>>();  // 組織架構關係;id->list
    private Map<String, String> invertedMap = new ConcurrentHashMap<String, String>();       // 反向關係鏈

    public GroupStructure(String groupId, String groupName) {
        this.groupId = groupId;
        this.groupName = groupName;
    }

    public boolean add(Employee employee) {
        return null != employeeMap.put(employee.getuId(), employee);
    }

    public boolean remove(Employee o) {
        return null != employeeMap.remove(o.getuId());
    }

    public boolean addLink(String key, Link link) {
        invertedMap.put(link.getToId(), link.getFromId());
        if (linkMap.containsKey(key)) {
            return linkMap.get(key).add(link);
        } else {
            List<Link> links = new LinkedList<Link>();
            links.add(link);
            linkMap.put(key, links);
            return true;
        }
    }

    public boolean removeLink(String key) {
        return null != linkMap.remove(key);
    }

    public Iterator<Employee> iterator() {

        return new Iterator<Employee>() {

            HashMap<String, Integer> keyMap = new HashMap<String, Integer>();

            int totalIdx = 0;
            private String fromId = groupId;  // 僱員ID,From
            private String toId = groupId;   // 僱員ID,To

            public boolean hasNext() {
                return totalIdx < employeeMap.size();
            }

            public Employee next() {
                List<Link> links = linkMap.get(toId);
                int cursorIdx = getCursorIdx(toId);

                // 同級節點掃描
                if (null == links) {
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 上級節點掃描
                while (cursorIdx > links.size() - 1) {
                    fromId = invertedMap.get(fromId);
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 獲取節點
                Link link = links.get(cursorIdx);
                toId = link.getToId();
                fromId = link.getFromId();
                totalIdx++;

                // 返回結果
                return employeeMap.get(link.getToId());
            }
             
            // 給每個層級定義寬度遍歷進度
            public int getCursorIdx(String key) {
                int idx = 0;
                if (keyMap.containsKey(key)) {
                    idx = keyMap.get(key);
                    keyMap.put(key, ++idx);
                } else {
                    keyMap.put(key, idx);
                }
                return idx;
            }
        };
    }

}
  • 以上的這部分代碼稍微有點長,主要包括了對元素的添加和刪除。另外最重要的是對遍歷的實現 new Iterator<Employee>
  • 添加和刪除元素相對來說比較簡單,使用了兩個map數組結構進行定義;僱員列表組織架構關係;id->list。當元素添加元素的時候,會分別在不同的方法中向map結構中進行填充指向關係(A->B),也就構建出了我們的樹形組織關係。

迭代器實現思路

  1. 這裏的樹形結構我們需要做的是深度遍歷,也就是左側的一直遍歷到最深節點。
  2. 當遍歷到最深節點后,開始遍歷最深節點的橫向節點。
  3. 當橫向節點遍歷完成后則向上尋找橫向節點,直至樹結構全部遍歷完成。

3. 測試驗證

3.1 編寫測試類

@Test
public void test_iterator() { 
    // 數據填充
    GroupStructure groupStructure = new GroupStructure("1", "小傅哥");  
    
    // 僱員信息
    groupStructure.add(new Employee("2", "花花", "二級部門"));
    groupStructure.add(new Employee("3", "豆包", "二級部門"));
    groupStructure.add(new Employee("4", "蹦蹦", "三級部門"));
    groupStructure.add(new Employee("5", "大燒", "三級部門"));
    groupStructure.add(new Employee("6", "虎哥", "四級部門"));
    groupStructure.add(new Employee("7", "玲姐", "四級部門"));
    groupStructure.add(new Employee("8", "秋雅", "四級部門"));   
    
    // 節點關係 1->(1,2) 2->(4,5)
    groupStructure.addLink("1", new Link("1", "2"));
    groupStructure.addLink("1", new Link("1", "3"));
    groupStructure.addLink("2", new Link("2", "4"));
    groupStructure.addLink("2", new Link("2", "5"));
    groupStructure.addLink("5", new Link("5", "6"));
    groupStructure.addLink("5", new Link("5", "7"));
    groupStructure.addLink("5", new Link("5", "8"));       

    Iterator<Employee> iterator = groupStructure.iterator();
    while (iterator.hasNext()) {
        Employee employee = iterator.next();
        logger.info("{},僱員 Id:{} Name:{}", employee.getDesc(), employee.getuId(), employee.getName());
    }
}

3.2 測試結果

22:23:37.166 [main] INFO  org.itstack.demo.design.test.ApiTest - 二級部門,僱員 Id:2 Name:花花
22:23:37.168 [main] INFO  org.itstack.demo.design.test.ApiTest - 三級部門,僱員 Id:4 Name:蹦蹦
22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 三級部門,僱員 Id:5 Name:大燒
22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四級部門,僱員 Id:6 Name:虎哥
22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四級部門,僱員 Id:7 Name:玲姐
22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 四級部門,僱員 Id:8 Name:秋雅
22:23:37.169 [main] INFO  org.itstack.demo.design.test.ApiTest - 二級部門,僱員 Id:3 Name:豆包

Process finished with exit code 0
  • 從遍歷的結果可以看到,我們是順着樹形結構的深度開始遍歷,一直到右側的節點3僱員 Id:2、僱員 Id:4...僱員 Id:3

六、總結

  • 迭代器的設計模式從以上的功能實現可以看到,滿足了單一職責和開閉原則,外界的調用方也不需要知道任何一個不同的數據結構在使用上的遍歷差異。可以非常方便的擴展,也讓整個遍歷變得更加乾淨整潔。
  • 但從結構的實現上可以看到,迭代器模式的實現過程相對來說是比較負責的,類的實現上也擴增了需要外部定義的類,使得遍歷與原數據結構分開。雖然這是比較麻煩的,但可以看到在使用java的jdk時候,迭代器的模式還是很好用的,可以非常方便擴展和升級。
  • 以上的設計模式場景實現過程可能對新人有一些不好理解點,包括;迭代器三個和接口的定義、樹形結構的數據關係、樹結構深度遍歷思路。這些都需要反覆實現練習才能深入的理解,事必躬親,親歷親為,才能讓自己掌握這些知識。

七、推薦閱讀

  • 1. 重學 Java 設計模式:實戰工廠方法模式「多種類型商品不同接口,統一發獎服務搭建場景」
  • 2. 重學 Java 設計模式:實戰原型模式「上機考試多套試,每人題目和答案亂序排列場景」
  • 3. 重學 Java 設計模式:實戰橋接模式「多支付渠道(微信、支付寶)與多支付模式(刷臉、指紋)場景」
  • 4. 重學 Java 設計模式:實戰組合模式「營銷差異化人群發券,決策樹引擎搭建場景」
  • 5. 重學 Java 設計模式:實戰外觀模式「基於SpringBoot開發門面模式中間件,統一控制接口白名單場景」
  • 6. 重學 Java 設計模式:實戰享元模式「基於Redis秒殺,提供活動與庫存信息查詢場景」

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

什麼是技術債,為什麼要還技術債?

先說我的結論就是:技術債要還,還不還技術債,決定你所在的公司是不是尊重科學尊重技術,觀點主要有一下三個:

  • 技術債是什麼,對產品和項目有什麼影響
  • 技術債對開發環境和技術氛圍的影響
  • 技術債和技術價值觀

技術棧是什麼,對產品和項目有什麼影響

既然叫技術債,那麼他本質是一種“債”,所以我們先脫離所謂的技術,單獨聊聊什麼是債?債是一個金融上的術語,代表你的負資產,說人話就是代表你欠了別人的錢,在著名美劇《冰與火之歌》裏面的蘭尼斯特家族有一句名言就是:有債必嘗

  1. 那麼生活中有哪些跟債相關的事情呢?我們日常接觸的債有哪些? 花唄,信用卡,透支下個月工資,貸款,高利貸 等等

  2. 債有什麼特點?債本身是一種透支行為,是你犧牲未來滿足自己當下的某種需求,而且所有的債都有一個共同的特點,就是利息,而且跟隨時間~利滾利

  3. 那麼債是怎麼產生的?大家可以想想你什麼時候會用信用卡,用花唄去購物,或者去借高利貸?當你渴望得到某一個東西,但是你本身還不具備購買能力的時候,你會去借債對吧,例如在你財務狀況還很差的情況下,你想買名牌包包,你想買最新款性能最好的蘋果電腦,你想買豪華轎車等等,通過透支未來,來滿足當下的需求,技術債為什麼叫債,就是通過借債,透支系統的擴展性,安全性,來達到快速上線功能目的,借債很容易上癮,為什麼?因為它可以讓你快速滿足慾望(物質,快速變現),嘗到甜頭

  4. 要麼有債要不要還?還債重不重要?:我覺得這其實是看你個人的選擇而已,你借錢也可以不還,可以賴賬,可以能拖一年是一年,甚至也可以忘記你借過的債或者否認它,這可以讓你獲得一些短期利益,讓你嘗到一些甜頭,例如技術上你也可以通過欠債,來快速的實現功能,但是不知道大家是否在意自己的信用和口碑,但在如今的文明社會正在構建就是個人的信用體系,國家徵信中心,支付寶的芝麻信用,微信的支付積分,都是在評價你的個人信用,你的還債的及時和履行契約的能力,最終都是體現在你的個人信用積分上,所以說有債不還也是可以的,這取決與你是否在意你的個人信用和口碑,但如果是一個信用不好的人那麼在一個信用體系如此完善的現代社會裡面是很艱難的,別人不敢跟你做生意,你做什麼時候都必須要先交押金,出行乘坐交通工作,信用好的可以走安全通道,你就必須過安檢和全身掃描,所以在不在債務,還不還債務,其實取決於你想不想做一個講信用的人,做一個用誠信為本去安身立命的人,如果你想做一個誠信為本的人,那麼就要放棄短期利益,把目光放的更加長遠一些,記得我曾經看過一個報道,是講京東創業的故事,京東的企業家劉強東對記者說,如果我們想要賺錢,那麼很簡單,我們有很多捷徑可以走,例如我們不給員工買交社保和五險一金,把大量人員全部轉去外包公司,那麼我們每年營業額馬上就會多十幾個億,可以馬上賺很多的錢,但是他沒有選擇這樣做,這樣通過透支的做事方式確實短期可以獲得一些利益,但是長期來看,你失去的人心,失去了企業的誠信

技術債對開發環境和技術氛圍的影響

產品的迭代就像一個運動員在跑步,汽車在前進,技術債就像運動員消耗的體力,汽車在運行當中所出現的各種問題,沒油,爆胎,熄火等等,還債就是給運動員補水,給汽車加油一樣,是為了可以讓運動員和汽車跑的更遠,不至於因為累積技術債而掛掉,為什麼要重視技術債和細節?因為魔鬼藏在細節當中,再舉幾個和生活息息相關的:

  1. 為什麼我們大樓每天檢修消防和安全設備,為什麼消防要經常做演習?在這些沒有真正產出的事情上耗費精力,難道不能等到真正發生火災發生後去撲滅和搶救嗎 ?
  2. 飛機是在起飛前,為什麼需要做那麼多的安全和檢查措施?確保沒有風險后,然後再執行起飛,難道不能先讓飛機起飛,等到出現問題后再去補救和修復嗎 ?
  3. 為什麼我們提倡每天鍛煉身體,健康飲食?為什麼每年要去醫院體檢?難道不應該等到你的身體已經出現問題,或者發出警報后,你再去看醫生嗎?

說到這裏,技術債的重要性毋庸置疑,重視技術債,就是重視於未然,已最低的成本或者零成本,防止未來的災難發生,還不還技術債很多時候是一種選擇,這些選擇決定了你有沒有預先判斷和解決問題的能力,那麼什麼樣的產品不用還技術債?一次性產品,例如一次性杯子,一次性手套用完就扔掉,所以如果產品長期的可持續的發展,那麼技術債的重要性是毋庸置疑的,對方辯友可能會說我們不是不還技術債,我們只是等做完緊急需求等到空閑時間再還技術債,但是經常做項目的同事應該了解,哪有什麼空閑時間?我們在項目衝刺的時候怎麼可能還會有空閑時間,大部分時間所謂的稍後處理,其實就是不處理,屬於掩耳盜鈴,當技術債被遺忘后就成為項目的定時炸彈埋在那裡了,而且技術債的特性前面也說了,所謂的稍後處理,就是讓它利滾利,拖延時間越長,還債的成本越高,而且人們還債的意願就越低,誰也不敢去碰它,例如,你身體出現問題,你不去看醫院檢查和修復問題,而是一直繼續使用和消耗你的身體,拖到最後實在不能動的,你沒辦法去醫院一查,癌症晚期,那時候神仙也沒救了, 而且技術債不單單是技術債,它就像一個垃圾堆一樣,久而久之不處理,慢慢周圍就會產生更多的垃圾,因此產生的“破窗效應”更加是會對未來的項目環境造成很大的影響,大家也會逐漸喪失維護環境的信心,所以我們在討論技術債的時候不僅僅是討論技術債本身,技術債對團隊追求質量的信心,對大家維護環境整潔的积極性都會造成很大的影響,所以我方觀點是,技術債,有債必嘗,越拖成本越高,最好是在發現的時候馬上處理它,不要讓乾淨的房間出現垃圾堆,只有在乾淨的環境下大家才能持續的高效的去創造,一個需求捏着鼻子做,兩個需求捏着鼻子做,久而久之代碼中就散發出臭味,對於大家的工作體驗和項目質量都會產生巨大的影響,如果連工作都不開心,那還談什麼夢想?沒有良好的技術環境企業就無法吸收和留住高質量的技術人才,人才是現代企業的核心競爭力,沒有人才的企業在瞬息萬變的市場上是難以做出快速反應的

技術債和技術價值觀

不重視技術債就是不重視技術,不尊重科學發展,不能客觀的認識和理解技術的複雜性和軟件工程帶來的價值和意義,我們國家近幾年就因為不重視技術吃了不少虧,比如去年的中興通訊公司被制裁,因為沒有自己的技術,芯片被斷供製裁后卻毫無還手之力,國產目前的大多手機廠商看似繁榮,但手機行業的 8,9 成利潤被都被掌握技術的蘋果公司賺走,打開現在的智能手機裏面你會看到,美國的芯片和谷歌的安卓操作系統,日本的鏡頭和相機模組,三星的屏幕,還要在微薄的利潤上繳納高通的芯片稅,實際上國內大多廠商做的都是代加工和組裝的臟活累活,沒有技術的公司,就會受制於人,不僅賺不到錢,而且公司的命運都是由掌握核心技術的公司決定,再比如一個近期的新聞,哈工大的建模軟件被斷供等等例子,不勝枚舉,那麼技術有多重要?我們就用華為來舉例,華為為什麼是一家值得尊重的科技公司,因為他打破了中國自從第二次工業革命以來,但是因為長期技術落後長期受制於人的客觀事實,中國以前的代號叫做世界工廠,只適合做一些勞動密集型產業,但華為讓中國企業在先進的技術領域,同樣是被美國制裁,為什麼華為活的比中興好很多?因為華為重視技術,從海思芯片到5G 再到操作系統,自己擁有產業供應鏈,有自己的的核心技術,才能掌握自己的命運,而且在取得商業上的成功后,也得到的大家的尊重,相同還有最近處於風口的台灣的芯片製造廠商台積電公司,全球唯二掌握 7納米芯片製造技術的芯片公司,因為自主的核心技術在擁有可以在國際上和英特爾平起平坐資本,綜上所述,不重視技術雖然也可以生存,但是重視技術,掌握核心技術,才能走的更遠,我們都知道技術的目的是要體現商業價值,但前提是要擁有核心技術才配擁有商業價值,沒有技術壁壘的企業和人隨時都可能被人替換,而且幾乎沒有什麼成本,重視技術公司才能發展的更遠,才不會受制於人,才能成為頭部玩家,收割行業90%的利潤,才有可能成為一家偉大並且受人尊重的公司,不然你去想想蘋果公司為什麼不放棄技術,微軟和谷歌為什麼不放棄技術,英特爾和高通為什麼不放棄技術,技術很重要,可以讓個人和企業提升競爭力,不容易被淘汰,對於國家和社會,二次工業革命以來,技術改變了我們的生產效率,從而改變我們社會的運行方式,技術幫助解決了困擾我們幾千年的《馬爾薩斯陷阱》,我們國家經歷過近代史的幾百年技術落後的屈辱后,更加的尤為重視技術,我們在1960 年代大家都吃不飽的情況下我們就研發出自己的原子彈,我們國家級的戰略目標《中國製造 2025》就包含的“芯片,人工智能,區塊鏈,機器人,新能源”等等高精尖產業,目的就是讓我們脫離低端製造業,脫離勞動密集型產業,因為沒有技術含量的重複性的勞動工作未來都將被機器和 人工智能 取代,在未來很難被取代就是人類特有的豐富的想象力和創造力。

最後我想再引用 一個真實的故事,是來源於 NASA 的著名文章《為什麼要探索太空?》,文章的背景是來源於 1970年,贊比亞修女 Mary Jucunda 給 NASA 科學家 Ernst Stuhlinger 博士寫了一封信,信中,Mary Jucunda 修女問道:目前地球上還有這麼多小孩子吃不上飯,他怎麼能捨得為遠在火星的項目花費數十億美元。Ernst Stuhlinger 在回信中寫到一個真實的故事如下:

那是在400年前,德國某小鎮里有一位伯爵。他是個心地善良的人,他將自己收入的一大部分捐給了鎮子上的窮人。這十分令人欽佩,因為中世紀時窮人很多,而且那時經常爆發席捲全國的瘟疫。一天,伯爵碰到了一個奇怪的人,他家中有一個工作台和一個小實驗室,他白天賣力工作,每天晚上的幾小時的時間專心進行研究。他把小玻璃片研磨成鏡片,然後把研磨好的鏡片裝到鏡筒里,用此來觀察細小的物件。伯爵被這個前所未見的可以把東西放大觀察的小發明迷住了。他邀請這個怪人住到了他的城堡里,作為伯爵的門客,此後他可以專心投入所有的時間來研究這些光學器件。然而,鎮子上的人得知伯爵在這麼一個怪人和他那些無用的玩意兒上花費金錢之後,都很生氣。“我們還在受瘟疫的苦,”他們抱怨道,“而他卻為那個閑人和他沒用的愛好亂花錢!”伯爵聽到后不為所動。“我會盡可能地接濟大家,”他表示,“但我會繼續資助這個人和他的工作,我確信終有一天會有回報。”果不其然,他的工作(以及同時期其他人的努力)贏來了豐厚的回報:顯微鏡。顯微鏡的發明給醫學帶來了前所未有的發展,由此展開的研究及其成果,消除了世界上大部分地區肆虐的瘟疫和其他一些傳染性疾病。伯爵為支持這項研究發明所花費的金錢,其最終結果大大減輕了人類所遭受的苦難,這回報遠遠超過單純將這些錢用來救濟那些遭受瘟疫的人。

綜上所述,重視技術債就是重視技術,重視技術就是重視細節和未來,魔鬼存在細節當中,細節決定成敗

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

程序員過關斬將–分佈式系統消息異常該何去何從

異步處理模型

一旦談到分佈式,微服務等這些具有很高逼格的代名詞,總能讓你在面試中脫穎而出,不是因為這些詞的英文翻譯的好,而是現代互聯網乃至企業級開發確實在分佈式,微服務等模式下取得了良好的架構效果。無論是微服務,還是之前的SOA,總是離不開異步處理模型,小到程序中IO的處理,大到系統間的消息交互,處處都有異步的身影。

談到系統之間的消息異步處理,就不能不談消息隊列(MQ),目前業界比較流行的MQ類型請自行百度腦補。但是需要提醒一下,MQ只是實現數據異步處理的一種解決方案,沒有MQ能不能實現異步處理呢?當然能,最簡單粗暴的莫過於採用數據庫方式,消息生產者直接把數據插入數據庫,消費者採用讀取數據庫的方式來獲取數據,所以MQ並不等於異步處理哦。

異步消息處理最大程度上解耦了各個系統,為每個系統獨立擴展提供了更大空間,但是異步消息處理也同時面臨着一些挑戰,比如:消息管道性能,消息管道的高可用等,其中最貼近業務層的可能非“數據異常處理”莫屬,基本上可認為這是數據處理模型的最末端,數據流向的尾部,但往往卻是業務中比較重要的部分。

如果一條異步消息作為一個分佈式事務中的一環,那還設計到消息處理結果的反饋,分佈式協調器會根據消息結果的成功與否來決定的事務的結果。

單就異步消息消費端來講,根據不同的業務場景就有以下幾種異常處理方案

直接忽略

這是所有異常數據處理方案中最粗暴,同時也是最簡單的一種:發生異常的時候,直接忽略,什麼都不做。

面對異常不採取任何措施,乍一聽這可能是個很糟糕的方案,但是在實際業務中,這可能是完全可以接受的。如果因為錯誤導致的損失很小,甚至可以忽略,但是建立一套錯誤糾正機制的成本遠遠高於忽略異常,這種場景下選擇直接忽略往往是一種更優的方案。而且當錯誤糾正機制設計到需要人工介入操作的時候,代價會更高,而且還會引入影響其他業務的可能,更為可怕的是如果錯誤糾正機制本身出現問題,那代價更是…..

舉個很簡單的栗子:像一些登錄日誌的統計操作,如果處理某個人登錄的數據出現異常,往往會選擇直接忽略。因為統計這種業務本身就帶有數據的容錯機制,100000和100001在統計需求看來沒有什麼區別。

重試

當直接忽略的方案不可行的時候,你可能需要重試的操作。如果在重試的情況下有足夠高的成功率,那重試就是合理的選擇。重試雖然可以改正間接性的錯誤,但是它對那些違反業務規則,違反數據模型的數據無能為力。

在最理想的情況下,如果重試操作是冪等性的,什麼叫冪等性能(自己去百度吧)?事情就會簡單很多,重試操作可以放心大膽的去實施。但是在重試操作經過一段時間或者一定次數之後還未成功的話,多數情況下可能需要有一定的後續策略,比如:重試10次之後如果還是失敗,則放棄。

補償

這個策略是分佈式事務中經常用到的,與其說是補償,不如說是回滾操作。特別是在程序接收到數據會有一系列的操作的情景下,補償操作類似於事務回滾的概念,讓系統回到發生這一系列操作之前的狀態。這種補償的機制非常適合於那種有“事務”需求的場景。

你的業務中有哪些“事務”的需求場景呢?歡迎在留言中體現,另外再稍微提一下,每周送架構書籍的活動仍然在進行哦,歡迎關注

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!