我们通常说的SpringCloud,指的是Spring Cloud Netflix,在独立的主机环境中也能使用部署,血统最为正宗,后面的文中,指的都是它。虽然有些组件不再维护了,但好在是可以热拔插的(除非你已经上了贼船)。
SpringCloud只是一堆规范,其中的组件是可以替换的额。私以为,如果你采用了SpringCloud技术栈,你就必须要搞一个自己的SpringCloud。受技术选择倾向和功能的影响,你可能会选了N家公司的不同组件进行集成,你的大多数工作其实是放在服务治理上。
本来,做些可以替换的starter组件,是皆大欢喜的事情,可云厂商们不这么想。话说这aws
,搞了个自己的SpringCloud
,集成了自己的众多的服务,相辅相成,卖的很好。于是Azure
等,也搞了一套,只不过只能跑在自己的云上。如果你用了,哪一天如果想换主机环境了,就会知道这些爸爸们是多么的爱你。既然有这等功效,东方的一寡头手痒了,也要追随时代的潮流。
因为垄断,是所有商业公司一生的追求啊。
<figcaption style="display: block; text-align: center; font-size: 1rem; line-height: 1.6; color: rgb(144, 144, 144); margin-top: 2px;"></figcaption>
这些坑爹项目,其价值甚至不如写个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默认的是Feign
和Ribbon
,主要是提供了远程调用请求和解析,以及负载均衡的功能。客观点来说,如果不用这两个组件,就会越来越四不像,干脆也别叫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是升上云端。俯瞰大地,多么美妙的景色,我都忍不住颤抖起来。
只不过,春回大地,全是狗屁。
欢迎工作一到五年的Java工程师朋友们加入Java高并发: 957734884,群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!