坑爹專案「spring-cloud-alibaba」,我們也來一個

小姐姐味道發表於2019-04-05

我們通常說的SpringCloud,指的是Spring Cloud Netflix,在獨立的主機環境中也能使用部署,血統最為正宗,後面的文中,指的都是它。雖然有些元件不再維護了,但好在是可以熱拔插的(除非你已經上了賊船)。

SpringCloud只是一堆規範,其中的元件是可以替換的額。私以為,如果你採用了SpringCloud技術棧,你就必須要搞一個自己的SpringCloud。受技術選擇傾向和功能的影響,你可能會選了N家公司的不同元件進行整合,你的大多數工作其實是放在服務治理上。

本來,做些可以替換的starter元件,是皆大歡喜的事情,可雲廠商們不這麼想。話說這aws,搞了個自己的SpringCloud,整合了自己的眾多的服務,相輔相成,賣的很好。於是Azure等,也搞了一套,只不過只能跑在自己的雲上。如果你用了,哪一天如果想換主機環境了,就會知道這些爸爸們是多麼的愛你。既然有這等功效,東方的一寡頭手癢了,也要追隨時代的潮流。

因為壟斷,是所有商業公司一生的追求啊。

坑爹專案「spring-cloud-alibaba」,我們也來一個

這些坑爹專案,其價值甚至不如寫個SpringCloud教程。

搞就搞,不就是一個全家桶麼。

接下來我們看一下,要實現一個SpringCloud,都需要做哪些步驟。

實現一個parent

顯得專業些,就弄個parent。類似的,如果你在搞基礎框架搭架子,也可以這麼搞。

當然作用也是有的。使用parent來控制版本和依賴,是經常用的手段。parent經常與BOM相結合,BOM也是由Maven提供的功能,用來定義一套相互相容的jar包版本集合,在pom檔案裡,就是指在dependencyManagement標籤中定義的部分。

使用時只需要依賴該BOM檔案,即可放心的使用需要的依賴jar包,且無需再指定版本號。BOM的維護方負責版本升級,並保證BOM中定義的jar包版本之間的相容性。類似這種:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
複製程式碼

BOM是很多開源軟體的組織方式,尤其是在元件較多,版本較亂的情況下,能夠為使用者提供一個比較統一的環境。

對於我們來說,就需要將常用的元件進行封裝,然後統一在BOM檔案中進行維護。第一,功能要全;第二,版本要相容。組裝一下,就是一個微服務框架了。

實現一些starter

使用過starter的人都知道,我們只需要引進相應的jar包,然後在yml檔案裡配置幾個引數,就能夠獲取豐富的功能。這種神奇的事情都是由SpringBoot Starter完成的。

類似於java的SPI機制,SpringBoot將自動載入src/main/resources/META-INF/spring.factories中配置的資訊,進行初始化操作。

接下來我們實現這樣一個功能:被Owl註解修飾的方法,將自動列印一行日誌。

加入依賴

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
複製程式碼

編寫註解

Owl.java

import java.lang.annotation.*;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Owl {
    String operationName() default "";
}
複製程式碼

編寫自動配置

OwlAutoConfiguration.java

@Configuration
@Slf4j
public class OwlAutoConfiguration {
    static final String TAG_COMPONENT = "java";

    @Bean
    public OwlAspect owlTracingAspect() {
        return new OwlAspect();
    }

    @Aspect
    class OwlAspect {
        @Around("@annotation(com.sayhiai.arch.trace.annotation.OwlTrace)")
        public Object owlTraceProcess(ProceedingJoinPoint pjp) throws Throwable {
            final String cls = pjp.getTarget().getClass().getName();
            final String mName = pjp.getSignature().getName();
            log.debug("cls:" + cls + ",method:" + mName);

            return pjp.proceed();
        }
    }
}
複製程式碼

載入配置

src/main/resources/META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sayhiai.core.owl.OwlAutoConfiguration
複製程式碼

接下來,將你的程式碼,打包成jar,在需要的工程中引入就可以了。

組裝關鍵元件

其實仔細的看下來,SpringCloud的關鍵元件就那麼幾個。既然是元件,那就能夠隨意替換,Netflix的版本做到了。

所以我覺得真要對社群有誠意的話,只需要獨立維護相應的元件就可以。全搞成自己的,心不在此啊。

一個元件,加上一個starter,完美而優雅的組合,頂絕而歡暢的樂章,就像Consul一樣。

不囉嗦,我們在《微服務不是全部,只是特定領域的子集》這篇裡講了大而全的圍繞著微服務的功能。在這裡,我們簡單談一下SpringCloud的關鍵部位。

一、遠端呼叫RPC 二、註冊中心 三、熔斷、限流 四、閘道器

遠端呼叫RPC

SpringCloud預設的是FeignRibbon,主要是提供了遠端呼叫請求和解析,以及負載均衡的功能。客觀點來說,如果不用這兩個元件,就會越來越四不像,乾脆也別叫SpringCloud了,所以替換不得。

RPC會大量使用動態代理的功能,將你的字串或者配置(因為網路傳輸方便)搞成動態的介面。

你也可以寫一個RPC進行整合,有很多教程教你手擼一個。

爸爸版的整合了個dubbo,dubbo就是個RPC。所以你一用這玩意,其他的一些關鍵元件也得跟著全套的換,元件就不叫元件了!

註冊中心

服務註冊中心是微服務的另外一個必備元件,用來協調服務提供者和呼叫者的相互發現,SpringCloud預設的註冊中心是Eureka。

爸爸版的用的是Nacos。Nacos的更新目前來看還是比較活躍的,但真沒有必要整合在一個Cloud中。Nacos最好的方式還是獨立釋出,然後維護一個starter。開發者可以按照自己公司的環境進行有選擇性的整合或替換。整合一個元件的成本是比較低的,遠遠低於刪掉一堆自以為是的功能。

SpringCloud還可以選擇Zookeeper,或者Consul,甚至Etcd等,,進行註冊中心的搭建。目前,Eureka宣佈不再維護後,Consul應該是首要選擇。

Consul自帶Dashboard和ACL,能夠看到大多數你所關心的資訊。為了能夠整合在我們公司的體系中,你可能會開發一些後臺管理功能,進行更多的控制。這部分開發簡單,只需要做個介面,直接通過API讀取Consul的資料就可以了。

整合自己的服務

假如你是一個服務提供商,不論是PAAS,還是SAAS,都可以封裝一下,進行售賣了。

比如你提供了CDN,那就封裝一個xxx-cdn-spring-boot-starter;你想要把自己的搜尋服務進行售賣,那就封裝一個xxx-search-spring-boot-starter元件。

starter的命名方式是**-spring-boot-starter,我們也要這樣,顯的比較專業,像是一個牛逼公司出品的樣子。

要多弄幾個,顯的自己的產品豐富;也要控制數量,避免學習成本太高;要繫結自己的產品,讓使用者一旦使用,就無法下車,形成所謂的粘性

當然,想要加上-incubator字尾進入孵化器,還是有點難度的。不過如果你的公司夠大,這些都不是事。

熔斷、限流

這部分已經被炒作成微服務體系的必備元件,但捫心自問,這個功能對於中小型的應用可能就是一個擺設。但我們還是要搞的,因為這是個賣點。

SpringCloud預設的元件是Hystrix,提供了多執行緒和訊號量來控制的不同方式。可惜的是Hystrix也宣佈不再維護了,官方推薦的替換版本是resilience4j。

熔斷限流功能其實是非常簡單的,同事花了一週時間就擼了個足夠用的元件。這部分的主要設計在於能夠簡單的應用,最好是能夠通過後臺配置實時生效。

爸爸版的是Sentinel,雖然也帶了個後臺,但是並沒有和註冊中心進行整合,搞了個不倫不類。

我要用Sentinel,我自己整合就好了,用你個大頭鬼。

閘道器

閘道器,可以做統一的降級、限流、認證授權、安全等,是微服務的又一個元件。SpringCloud預設的是Zuul,Zuul又有版本1和2之分。SpringCloud還可以選擇Gateway進行閘道器控制。

你的公司用閘道器了麼?我保持疑問。見過很多到了C、D輪的公司,依然是簡單的Nginx簡單路由。

還有一種與語言無關的閘道器就是基於Nginx的Openresty,包括整合度更高的Kong。但這個商業化趨勢很明顯,故意將簡單的事情複雜化,穩定性待考究,很有手段。

我的意思是說,閘道器不是必須的,也沒有好用的閘道器。這是個五十步笑百步的領域。

其他

微服務中其他重要的元件,包括日誌收集、呼叫鏈、持續整合等,這些SpringCloud們都沒有提供。這就對了。都是開發者,我們會自己選擇。

重要的元件不整合,反而整合了一堆類似於OSS、ANS、SMS、MQ等非必須的功能,這就是偷奸耍滑了。

宣傳造勢

編寫example

什麼都可以沒有,但文件和例子要有的。這和幣圈ICO的白皮書一個道理。大家看概念很牛逼,可真正用的就沒幾個。

要炒概念,抓龍頭。

例子要能夠跑起來,當然使用者花點力氣也是可以的。如果使用者跑不起來,那絕逼不是產品問題,而是使用者的能力問題。

營銷

王婆賣瓜自賣自誇的可信力不大,你只需要在釋出會或者分享會上露露面就以了。剩下的就交給舔狗們吧。只要行動上符合我們的大戰略,那都是自己人。

一定要蹭蹭熱點,什麼火往什麼上靠。領導既然抽出人力讓你搞一個以公司名義的開源專案,那自然是醉翁之意不在酒。不拿出點非常手段,不取得點驕傲的成績,那是說不過去的。

如果你有經費的話,那再好不過了。當然,碰上個能花數億元收購Flink的團隊只是運氣。現在,你只需要花幾十塊錢,就能買到一篇軟文,KPI高了拿獎金可是要好幾萬的,這點帳不會算那還是別混了。

趕緊拿起手邊的電話訂購吧。

如果你的框架實在是沒有什麼特色的話,可以拿知名的開源軟體,或者公司內的其他優秀軟體站臺,互惠互利。做的不成熟不要緊,反正你用的又不是開源的版本。泥坑留給別人,芬芳留給自己。都是成年人的世界,沒必要那麼矜持。

#End

以名詞的角度來看:Spring是春的意思,Cloud是雲。

以動詞的角度來看:Spring是發春,Cloud是升上雲端。俯瞰大地,多麼美妙的景色,我都忍不住顫抖起來。

只不過,春回大地,全是狗屁。

坑爹專案「spring-cloud-alibaba」,我們也來一個

相關文章