我们通常说的SpringCloud,指的是Spring Cloud Netflix,在独立的主机环境中也能使用部署,血统最为正宗,后面的文中,指的都是它。虽然有些组件不再维护了,但好在是可以热拔插的(除非你已经上了贼船)。

SpringCloud只是一堆规范,其中的组件是可以替换的额。私以为,如果你采用了SpringCloud技术栈,你就必须要搞一个自己的SpringCloud。受技术选择倾向和功能的影响,你可能会选了N家公司的不同组件进行集成,你的大多数工作其实是放在服务治理上。

本来,做些可以替换的starter组件,是皆大欢喜的事情,可云厂商们不这么想。话说这aws,搞了个自己的SpringCloud,集成了自己的众多的服务,相辅相成,卖的很好。于是Azure等,也搞了一套,只不过只能跑在自己的云上。如果你用了,哪一天如果想换主机环境了,就会知道这些爸爸们是多么的爱你。既然有这等功效,东方的一寡头手痒了,也要追随时代的潮流。

因为垄断,是所有商业公司一生的追求啊。

这些坑爹项目,其价值甚至不如写个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是升上云端。俯瞰大地,多么美妙的景色,我都忍不住颤抖起来。

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

文章目录