一个微服务多小为好:在两周内可以完全重写
服务越小优点和缺点都会更加明显
修复并部署一个服务,不影响其他服务
不同服务,采用不同技术栈
一个组件不可用,会不会导致级联故障
可以只对有性能瓶颈的部分进行扩展,而不会因为一个地方的性能瓶颈导致会整体进行扩展
可以把微服务看成SOA的一个特定方法
比如:maven
java直到9才有模块的概念,OSGI最初是Eclipse Java IDE使用的一种安装插件的方式
模块的概念内嵌在 Erlang 语言的运行时中,你可以对 Erlang 的模块进行停止、重启或者升级等操作
构架师最恰当的比喻“城市规划师”,架构师应该像城市规划师那样专注在大方向上,只在很有限的情况下参与到非常具体的细节实现中来。他们需要保证系统不但能够满足当前的需求,还能够应对将来的变化。
重用代码可能引入的危险。在重用代码的驱动下,我们可能会引入服务之间的耦合。有一个我接触过的组织非常担心这个问题,所以他们会手动把服务代码模板复制到各个服务中。这样做的问题是,如果核心服务代码模板升级了,那么需要花很长时间把这些升级应用到整个系统中。但相对于耦合的危险而言,这个问题倒没那么严重。还有 一些我接触过的团队,把服务代码模板简单地做成了一个共享的库依赖,这时他们就要非常小心地防止对DRY(Don’t Repeat Yourself,避免重复代码)的追求导致系统过度耦合!这是一个很微妙的话题
我的经验是:在微服务内部不要违反DRY,但在跨服务的情况下可以适当违反 DRY
治理通过评估干系人的需求、当前情况及下一步的可能性来确保企业目标的达成,通过排优先级和做决策来设定方向。对于已经达成一致的方向和目标进行监督
演进式架构师应该理解,成功要靠不断地取舍来实现。总会存在一些原因需要你改变工作 的方式,但是具体做哪些改变就只能依赖于自己的经验了。而僵化地固守自己的想法无疑是最糟糕的做法。
可能有同一个名字,但是数据结构却大不相同
相比编排,优先选择协同
请求/响应一般可以考虑:rpc和rest,其中rpc实现一般有soap、thrift、protocol buffers、rmi。soap底层用xml和http,thrift和protocol buffers使用二进制和tcp。rest比rpc更好,rpc由于接口参数的变动很可能会引起问题,比如rmi,thrift、protocol buffers虽然解决了这部分问题,但是相比rest而言还是不够稳定。rest一般用http实现,当然也有用其他技术的实现
atom或者消息队列
语义化版本管理的每一个版本号都遵循这样的格式:MAJOR.MINOR.PATCH。其中MAJOR的改变意味着其中包含向后不兼容的修改;MINOR的改变意味着有新功能的增加,但应该是向后兼容的;最后,PATCH的改变代表对已有功能的缺陷修复。
等老接口完全没人访问了,再把老接口去掉
拦截对老接口的调用,分析是走老接口实现还是新接口实现
可以一个一个业务这样增量的拆分,大单体应用不太可能一次性就拆分好
最好的采用配置文件
比较缓冲的做法是先拆分数据库,应用不拆分;然后我们数据库分离感到满意后再拆分应用
尽量用jta这种现成的规范
利用发消息,尽量用最终一致性,对于还处于不一致中的数据,可以想一个处理中的概念来表示,比如“处理中”的订单
使用单独的数据库存储,比如:mongodb、hbase、cassandra
可以使用服务提供的api生成报表
服务修改数据发送事件给报表服务
使用流式大数据处理技术
设计系统的架构受制于研发团队的组织结构
猴子军队,混乱大猩猩
使用断路器时,当对下游资源的请求发生一定数量的失败后,断路器会打开。接下来,所有的请求在断路器打开的状态下,会快速地失败。一段时间后,客户端发送一些请求查看下游服务是否已经恢复,如果它得到了正常的响应,将重置断路器。
采用副本机制,比如备数据库、缓存
采用分片方式,利用一个hash函数计算出数据存储在哪个节点,难点在于处理多数据查询的问题,有些数据解决了这些问题,比如es、mongodb、cassandra
command-query responsibility segregtion,命令查询职责分离
使用后写式缓存,如果对写操作的缓冲做了适当的持久化,那么即使下游服务不可用,我 们也可以将写操作放到队列里,然后当下游服务可用时再将它们发送过去。
当前端缓存服务挂了后,请求会被转到了源服务,这样会导致源服务被打垮,我们可能采用快速失败的,然后发送事件通知源服务重新同步缓存
在分布式系统中P肯定是存在的,无法避免,所以分布式系统有ap或者cp系统,ap一般叫做最终一致性。许多情况下,AP系统都是最终正确选择。