容器相关

几个问题
1,不同发行版的docker容器,尤其是glibc这些底层库版本不一致的情况下,可以在同一个宿主下运行,是因为glibc这些库与系统内核提供的ABI一直都保持不变吗?万一内核升级,有ABI变动了,docker是如何处理的呢?
处理办法是镜像自己带着基础库,事实上大多数发行版docker镜像都带着glibc,alpine用的则是更轻量的musl。镜像封装的应用,就只需保证兼容自带的glibc/musl即可。

2,现在虚拟机,都支持将某个虚拟机的窗体,直接投射到宿主机上,让宿主机像操作本地应用来操作虚拟机的应用,这个算那一层的虚拟化呢?也是通过ABI模拟来实现的吗?
说的是vmware unity mode这类功能么?具体如何实现的我没有研究过,无责任猜测只是vmware tool这样的工具提供的屏幕映射。但可以肯定的是,并不影响虚拟化层次,即还是硬件抽象层虚拟化。

3,在windows的vmware或virtualbox运行macos的虚拟机超级慢,但运行ubuntu就还蛮快的,是因为mac到win的ABI很难模拟吗?
“超级缓慢”主要是GUI慢,这个与显示方式和驱动都有关。如果你在SSH到虚拟的ubuntu和macos上,跑个console下的跑分软件的话,得到的分数相差并不大。

Windows 系统中是否有文件、访问、资源的隔离手段?是否存在 Windows 版本的容器运行时呢?
Windows的容器还是太重了,镜像超级大,而且优先支持微软自己的技术栈。这么重,加之不成熟,现在对上服务器虚拟化的各类成熟方案,实在没啥优势可言。

WindowsServer从设计上来讲,模块化做的比linux要差一些,内核做的事情也太多,早期类库变化也过于剧烈,类库前后兼容性也不算好。加之之前主推的技术,生命周期都太短,自家技术代与技术代之间没有传承,闭源得不到社区支持,开源服务端软件,在linux上性能,往往吊打windows。

而且即使是windows的虚拟化软件,微软自家做的也不是最好的。vmware和virtualbox多香。

微软唯一让我感到惊艳了一次的,还是wsl,但总归功能差了些,性能差了些。我倒是觉得,把wsl做好,可以同时支持win和linux容器,windows可能更有机会一些。

再后面,就是微软家生态的事情咯。其实微软做的很多理念,都挺超前的,而且也开始与社区合作。但微软,啥都要自己造轮子,技术延续性差又不断要大家换轮子,又没有强援,做生态挺难的。

看下linux和java,一个轮子能用多少年。看一下苹果,也是闭源,也是自己造轮子,还要交保护费,但苹果也不要你三五年就把轮子换了啊,而且保护费不是白交啊。远了远了。。。

docker
我觉得docker和其他虚拟化技术比,仍是最成功的,从docker到containerd,是一种技术上的成功,但是商业上的失败。

k8s应当与swarm对比。k8s成功,源自于google需要这样的一套工具,用来管理自己的容器,开发来先自己用,积累了很多经验。swarm则没有这个过程。云厂商们,自然选择对自己更好用,更有利的工具咯。

google至此,已占有web流量制高点,浏览器制高点,移动操作系统制高点,云原生制高点。厉害

网络虚拟化
N年前,在大学用虚拟机的时候,就遇到了HostOnly,Bridge,NAT等联网模式,当时对Bridge和NAT的区别也是搞了挺久才弄清楚的。

系统对既有旧方案和旧功能的兼容
这种例子蛮多的,比如:
1、系统升级时,如果API版本升级到了2.0,1.0版本也要长期保留。
2、界面风格变化了,还能允许用户切换回之前的风格
3、做系统替换时,一些用户用惯了的工具、报表什么的,经常会被要求在新系统上增加对应功能
4、系统升级时,尽量去兼容原有数据库设计,而不是推翻重来
5、对于部分政企用户,被迫去兼容IE,全是泪啊

存储
存储小文件:用过本地存储、SSD、SAN、NAS、SFTP、Ceph【对象存储】,云存储【云盘、对象存储】
存储大文件:用过SAN、NAS、Ceph【块存储】、HDFS
存储XML用过existdb、Oracle XML DB
存储JSON用过mongodb、es
备份数据,用过磁带和蓝光盘
试过IPFS,但并没有实际投入使用

从底层介质来看:可以分为SSD、磁盘、磁盘阵列、磁带、光盘等
块存储,相当于划分了一块存储空间或一块逻辑盘,给了操作系统
文件存储,相当于操作系统在磁盘上创建了文件系统,可以作为本地磁盘使用,加上网络访问功能,可以封装成为NAS、SFTP等
HDFS,可以看作分布式的文件存储
对象存储,可以看作分布式的NAS
IPFS,可以看作把一个BT网络,封装成了一个NAS

在我们行业里,使用云存储最大的障碍是两个:
1、使用公有云,担心数据安全、用户隐私的问题;少量上云的数据,也因种种限制,只能用移动联通电信的云;
2、使用私有云,很多机构不愿花大价钱购买服务,又没有能力自己运维,最终很难推进;
但总的来讲,这几年,云存储的使用面还是越来越广的,需要有个渐进的过程。

网络透明
服务网格可以实现透明,很大程度上是服务网格的整个网络环境是相对可控的。
远程通讯,如果在网络可控的环境下,其实完全可以和服务网格采用同样的方式。
但在互联网环境下,无法实现网络的可控,运维工程师、网络工程师是无法把程序员的大部分工作都做掉的,也就是程序员不能只关心数据,不关心网络。

何时能实现这种透明呢?个人认为,需要网络设备更新换代才行,要华为、思科支持这种透明,并能将透明能力,一定程度上开放给开发应用的厂商,才有可能实现一定程度上的透明。

SDN
个人感觉,SDN与服务网格感觉从思想上很相似,实现途径却不一样。

SDN本身十分依赖于网络提供商,其实按我理解,需要一次网络设备更新换代才行,而且网络提供商也需要进行一次大升级,用户也要跟着改造,这一方面需要技术沉淀,另一方面需要很多资金投入,一方面需要等用户升级。SDN概念也比较早,在网络提供商向用户推销SDN概念时,多数网络用户第一反映很可能是一脸懵逼。很多用户根本听不明白,有啥用,现在感觉挺好的啊。

而服务网格,是在可控网络下进行的,不需要网络设备的更替,也不需要以来网络供应商,更不存在跨越网络供应商的问题。大厂支持,再加上K8S和Istio的加持,所以生态就起来了,有滋有味的。服务网格用户是技术人员,服务网格出来推广的时候,微服务已大行其道了。技术人员们被服务治理烦的不要不要的,一听有方法直接把自己解放出来,学习应用热情高涨。加上并不需要夸张的资金投入,方案也就更容易落地了。

故障恢复

故障恢复
之前做个一个折中的处理方案,类似于快速接收,批处理,反馈处理状态。之所以这样处理,是因为合作机构IT水平参差不齐,而且配合程度不高,如果把数据接收+处理+反馈放到一起的话,一旦有错误,就要麻烦对方重新推送最新数据,或者自己脚本重新处理数据,而且一天峰值十分明显,峰值时根本来不及处理数据。
1、数据接收阶段,采用了快速失败策略。一旦数据落库文件落盘,就返回成功,反之失败。
2、数据处理阶段,会进行重试,三次后进入失败队列
3、进入失败队列后,会通知运维和开发,去看下数据什么问题。有时会把文件手工处理一下,再重试。如果实在无法处理,就线下通知合作方相关人员如何修改数据。
4、数据处理成功后或彻底失败后,发送处理结果给合作方。

这种方式,在对合作方约束很小、合作方缺乏技术支持、项目前期阶段、以快速开展业务为优先考量时,可以尝试一下。后面自己做起来后,就可以要求对方,做一些统一要求了。

限流和降级
之前在一个大量读写小文件服务的入口处,用过令牌桶限制访问量,防止IO过高。问题是每秒要发放发放多少令牌,最后是慢慢试出来的。

后面微服务时代就是中规中矩的限流,降级和熔断了。但降级和熔断,是通过HTTP状态码进行判断的,有些后知后觉了。

零信任网络
一个团队去完成一个任务,如果彼此信任,相互配合就会很流畅,沟通成本会很低,任务推进也会很顺畅。比如几个知根知底的伙伴去创业,一个眼神可能就懂了。
一群互不信任的人去完成一个任务,哪怕每个人都很努力,但经常感觉别人掣肘,吵来吵去,任务止步不前。一个流动率高,甩锅成风的组织,便是如此。

代码也是如此,如果我们假设代码是可信的,直接拉取镜像就行了。
如果假设代码是不可信的,开发提交代码后,要各种引擎扫描,扫描通过后,流水线打包镜像。同时还要提交各类材料如测试报告,越权测试报告,渗透测试报告,压力测试报告,代码审核报告等等相互佐证代码没有问题,然后发布。
这样先不说要多少资源支持,单说发布,就从十几秒变成了十几分钟,甚至几十分钟。

服务也是如此,如果假设服务是可信的,不要加任何控制,就可以相互访问。
如果假设服务不可信,就要各种验证,网络端口是否允许访问,token是否正确,双向证书过了没,是否有服务访问权限,是否有数据权限,是否符合流量控制要求等等。
先不说做需要多少资源支持,单说服务性能,从几十毫秒一下到了几百毫秒。

那做这些值吗?值!
但要符合自己的情况,不能太过,绑了自己的手脚!

零信任网络安全
我认为边界安全模型和零信任模型会长期共存,边界安全模型毕竟更成熟,而且在资源隔离程度上,远高于零信任模型。istio们并没有提供边界模型的一些组件,比如杀毒,比如入侵检测,比如蜜罐,比如上帝视角的规则控制等。而且istio们本身也有被入侵的可能,所以不能只依赖这一个层面的安全管控,而是立体的安全管控。

可观测性
单体程序时代,类似于一个办公大楼,有了问题,告诉管理员门牌号和具体事情就行了,管理员就可以乘电梯过来解决问题。
只要在日志里输出一下,哪个方法,做了哪个任务或出了什么问题,用日志工具就可以统计到处理速度或快速定位到问题了。

微服务时代,类似于管理城市物流。要提出问题,我们必须说明,那条街,哪个门牌号,几单元,有什么需求。工作人员上门时,要看下地图,什么路线过去最快,遇到堵车怎么办,小区不让进怎么办,然后才能到顾客这边提供服务。数据链路就像城市地图,监控就像地图上的流量,而日志必须还原到这张地图上,才知道哪个交叉口或哪个大楼哪里出了问题。
所以,我们要花必要的精力,去做全链路,绘制这个地图。所以我们要收集度量信息,去监控哪里流量红了,哪里彻底堵车了。只凭日志,是无法快速定位问题的,这个交叉口堵车,问题可能出在三公里之外,一个交叉口一个交叉口查过去,太慢了。

流量大了,堵车是必然的。只有做好可观测性,才能快速疏导交通,做到事半功倍。

日志
个人觉得,如何正确的记录日志,用何规则做日志分级,要记录哪些东西,比用什么技术栈分析日志重要的多。老师能否分享一下,日志规范如何在团队中落地呢?

有两种情况,多记录一些日志有好处的。一类是部署于第三方的系统,宕机时要多记录日志,最好有dump文件,利于排查问题。第二类是跨公司做集成对接,输入输出一般都会记得很清楚,为了防止扯皮。

聚合度量
主要监控了服务请求,JVM,服务器的一些指标。但服务请求方面,做的还很基础,有较大提升空间。

分布式相关

共识机制
Basic Paxos在全部节点可信任的时候,主要还是效率问题。所以zk、etcd都要用改进的算法。
Basic Paxos在部分节点不可信任的时候,是不适用的。所以公共区块链项目需要用其他的共识机制。

公共区块链中,常用的共识方法有PoW、PoS、DPoS等,这些方法,一方面是要达成共识进行记账,另一方面是要防止网络被恶意攻击;
联盟链中,一般采用PBFT、PoET等方法,由于不需要面向整个互联网,所以共识机制效率比公共链高不少;同理RAFT、ZAB,默认所有节点是可信任的,效率也是比较高的。
其实大家在日常生活中,默认会通过中心化的方式来达成共识,比如转账成功与否,大家一般会通过银行或支付宝的记录来判断,而不是线下协商。而这种方式,反而是交易效率最高的。
还是那句话,根据业务场景,选择足够用的架构和算法就好了。适合团队,能高效低成本解决问题的方案,就是最好的方案,哪怕这个技术方十分十分的朴素。

为何有了 DNS,还会出现 Eureka、Consul 这些专有的服务发现框架?
感觉其实要解决的问题并不一样:
1、基于DNS,其实要解决的问题是流量的流向,可以做到流量监控,但无法管理到具体业务,功能简单,效率更高;正好符合K8S的需要;
2、服务发现框架,其实是深入到业务层面,在应用框架集成、业务监听支持、健康检查、服务保护等功能。而且基于业务需求,进一步提供配置管理、环境管理等、多数据中心管理、业务紧密结合的功能;
有点像前面说的四层负载和七层负载的意思。
一个功能简单,效率高花头少;一个功能复杂,效率低可发挥空间更大;

那么除了 BFF 之外,你还用网关来做什么?
在API网关之前,会把移动APP的后端服务单独独立出来,APP访问APP后端服务,APP后端服务访问Web后端服务,相当于做了一个完全定制化的API网关。
当时也尝试过直接用Nginx来完成,但当时也不知道OpenResty这类扩展,复杂些的功能没能实现,没能实际应用。
后面从Zuul开始就不造轮子了。

客户端的负载均衡
客户端的负载均衡,在传统的CS解决方案中也有涉及,比如:
1、直连数据库时,统计类SQL直连只读库就好了
2、而且有些其实也变相做了优化,比如大家都熟悉的游戏开新服,登陆时就把流量分了

客户端负载均衡方案,其实和nginx的均衡策略基本一致的。但还遇到过一种中间情况,就是多了一个调度器,客户端定期获取服务IP列表,也可以从调度器获知每个IP的繁忙程度,然后决定要访问那个IP。

此外,云厂商对于移动、联通、电信的网络,有时也会用不同的链路,并会交一定的“保护费”啦。

负载均衡的设计,最佳人选,应该是懂业务的架构师(默认架构懂开发、懂运维)。
但同时,开发、运维团队要参与及评审:
1、比如开发要与架构沟通,团队熟悉哪些技术栈,哪些服务有状态哪些服务无状态等,中间件如何取舍
2、比如运维要与架构沟通,跨机房数据同步要如何做,容灾备份要如何处理,动态扩展是靠脚本还是靠云平台机制等

认证的各类方式

补充一下认证方式,一般是由三大类方式及其组合实现:

What you are:
比如人的生理特征(指纹、面部识别、虹膜、声纹、DNA等)

What you know:
古代机关开启方式、密码、动态指令、预设安全问题、最近和谁聊天、最近几次变动的密码、最近几次登录地址等

What you have:
身份证,医保卡,银行U盾牌,手机短信/电话语音发送验证码

但有一些就不太会好判断归属:
1、公安局开的身份证明或CA颁发给机构的证书,应该是“你有啥”,但很多时候直接被用于“你是谁”
2、图形动态验证码,用于判断“你是人不是机器”,这个算是“你是谁”的简单版本?

令牌内容
令牌不需要带太多的信息,但要满足一些基本要求:
1、令牌颁发机构标识
2、令牌被授予机构、APP、服务或网站标识
3、令牌类型(资源访问令牌、刷新令牌等)
4、令牌可访问的资源类型(头像、昵称、二维码等)
5、令牌有效时间范围
6、令牌颁布机构签名和时间戳
7、数据组织方式其实用Json 或 编码过的字符串都可以
这样,三方就都可以快速验证令牌有效性。

数据权限
数据权限确实很多时候只能系统自己处理,很难跨行业通用,甚至同一行业不同机构也不尽相同。比如两个看似比较通用的场景:
1、当机构架构分为多级时,上级机构能看到下级哪些数据,平级之间能看到那些数据,下级机构能看到什么数据,各行业各类组织互不相同。如果只用功能权限的思路去解决这个问题,容易将功能权限弄得十分复杂。
2、此外就是用户情况比较复杂,比如除了组织架构、岗位、职级外,还有职业证书相关权限控制、客户业务办理关系、项目组组成、项目组轮班,加上审核、稽核、多级质控等功能,仅是功能权限也是力有不逮。
而且,近些年来,各公司对数据权限和数据安全的要求都越来越高、越来越严格了。

凭证
感觉中文的“凭证”指的内容,比Credentials范围广很多。比如:
有时候,网页提示“请输入登录凭证”,说的就是用户名密码
有时候,请下载云主机“临时凭证”,说的就是登录证书
有时候,请出示入场凭证,说的就是一张狗牌

尤其是证书是否算凭证,感觉有些想不清楚。比如:下面的算凭证吗?
1、域控认证,Windows凭证管理器
2、Linux服务器可以通过ssh证书直接访问
3、一些云厂商可以申请临时ssh证书,允许远程访问
4、IOS程序发布时,需要开发者申请APP证书,并签名才能上传发表
5、接入云SDK时,需要申请AppId 和 SecretKey
6、TCP通讯时,采用TLS双证书双向加密

客户端敏感数据加密
对于客户端敏感数据加密的问题:
1、客户端对敏感信息加密,在通用浏览器、开放网络环境下,其实意义不大。如果一位黑客有能力干掉HTTPS通讯加密或者伪装为服务网站的话,替换掉网站前端代码也不是一件难的事情,这样无论如何加密信息都没有任何用途。同时,在客户端、服务的,这些敏感信息其实都有原文的,如果贡献了这两个地方,黑客可以同时获取明文和密文,所以加密也没啥用。
2、对于安全要求特别高,采用特殊通信协议,特殊信道,特殊设备、特殊浏览器的情况下,对于特别敏感的信息,进行二次加密是有必要的。因为设备和软件都难以得到,即使信道被监听,通信加密被破解,也要尽量拖延敏感信息被破解。

字证书有什么具体应用
1、机构、网站、身份认证
2、APP开发者认证
3、可执行程序开发者认证
4、控件开发者认证
5、API认证
6、文档的电子签章证书
7、大家自己搭建开发环境时有时需要自签名证书
其实还有很多咯。

除了顶级CA之外,其实CA也分等级的,这就涉及到了证书链。
此外,CA还要维护黑名单,吊销一些还在有效期之内的证书。

数据验证
之前只是零零散散有了一些想法,也落地了。但看完今天老师的讲解,感觉落地的很难看。

数据校验这部分,回顾了一下,我们真的做了很多,但十分十分的零散。根据各种要求,包括架构、运维、数据安全、数据合规要求、数据脱敏、敏感数据加密,每年都要折腾个几轮。此类代码横跨了文章中提到的全部层,实现方式从单纯的编码规范,到各层编码,到切面,到流水线扫描,到Jar包,到中间件、到持久化层验证,都有零散涉及。如果能尽量统一到 Bean Validation处理,就不至于每次加个要求,都要一通大改了。

缓存的弊端

1、增加了整个系统的复杂度,增加了系统的故障点,系统的整体可靠性可能会下降。比如Redis遇到bigkey,处理不好会让系统性能明显下降;如果Redis所在服务器CPU或内存资源不足,也会引起严重的性能问题
2、增加缓存后,缓存的预加载、过期失效、击穿、穿透、雪崩等问题,需要付出额外代价去解决
3、增加缓存后,缓存与数据库数据的一致性是个难题,需要付出额外代价去解决
4、分布式环境下,各缓存之间的数据同步及一致性,也是个难题,需要付出额外代价去解决
5、分布式环境下,缓存的高可用及冷启动后快速恢复,需要付出额外代价去解决

各类HTTP性能优化方式

网络性能优化

资源预下载,资源异步加载,资源压缩,dns加速,静态资源内容分发,多机房服务器就近访问,购买多条网络链路,防火墙过滤非法请求,F5负载,反向代理,API网关,多实例部署,缓存加速,一致性Hash分流,DB分库,异步任务队列等等。

其实还有P2P加速,网盘文件特征码上传加速,多网卡带宽绑定等特殊手段。

HTTP3
HTTP3的广泛推广,需要电信运营商的大力支持,同时还需要华为、思科等网络设备厂商的大力支持。以往各大电信运营商对UPD限制较多,各种网络设备对TCP的优化也更多。如果HTTP3广泛使用起来,对设备厂商也是个设备升级换代的好机会。

负载均衡
负载均衡和去医院看医生有些相似的:
1、刚到医院,要去分诊挂号,护士和挂号台的人不会问你一堆信息,只询问最基本信息并确定要看哪个科,就可以了。(四层负载,所需信息简单,工作效率高,重在吞吐量,不要有阻塞)
2、到了科室,尤其是看很繁忙的科室,会有护士和年轻医生,各种询问患者的情况,甚至把一些基础检查都做了,才会让专家去进一步提供服务;(七层负载,所需信息复杂一些,效率低一些,但好在量小了,也就避免了阻塞)
3、然后是资深医生看诊(实际网络服务)

但如果反过来,分诊挂号的时候,就咨询一大堆的问题,并作一些检查,每个患者耗时都长,会造成拥堵,患者排队n小时,而且到了科室就没有二次分诊的必要了。所以,七层代理放到前面,吞吐量就差了,四层代理也就没有存在的必要了。

负载均衡

各种事务实现方式

本地事务
Logging是无奈之举,因为操作系统和硬件的有效性不是100%,所以需要处理系统挂掉的情况。在系统挂掉后重启,数据库要知道需要Redo哪些操作,Rollback哪些操作,一定要有一个地方提前记录下来才行;相当于日志做了提前记录,数据库再做操作,根据日志的事务节点,就知道发生异常时数据要如何处理了。

Shadow Paging处理并发时,应该很难实现MVCC这种花式操作吧,多个客户端多个事务难以并发处理。

全局事务和共享事务
之前尝试过分布式事务,但实现效果实在太差,一个DB的事务卡住了,有可能卡住其他DB上的事务,性能直线下降。后面将强一致的场景进行了识别,尽量改造将其移动到一个库,其他直接通过异步等待方式解决,性能提高了不少。不需要强一致的,直接kafka同步搞了。

可靠消息队列
XA使用少,主要是其实现复杂,吞吐量低,会导致其他业务的阻塞,对于高并发访问,得不偿失。
可靠性队列,要轮询,会导致访问量增加,服务器负担上升,而且设计不良容易雪崩。同时,数据存在一段时间的不一致状态,但在可接受的情况下,性能远远优于XA。其实很多业务在重新调整事务顺序后,短期不一致状态的危害会很小。

本地事务

服务调用发展趋势

几类方法对比
CORBA看起来比较烦,用好了比较难,写起来比较烦,但好在起步早啊,而且贵在不断缓慢进步;
DCOM一心要兼容COM,有些反人类,看起来就烦,用好了很难,写起来很烦;
Java RMI、JAVA EJB,都是犯了相同的错,标准太烦了,对开发人员太不友好了。

WebService是看起来容易,用好了很难,写起来很烦;但同时代其他协议都是看起来就很难,所以胜出了,在一段时间内大行其道;

后来REST出现了,看起来容易,学起来容易,用起来也很容易。轻松将WebService挑落马下。

再看现在的Dubbo、Thrift、gRPC等,使用都相对简单,容易上手,开发者友好。
WCF有些小奇葩,很多想法很好,就是重了些,管得有些多,配置有些烦,如果要更多的占领市场,就应该让其变得更容易使用才对,而且应该跨平台才行。反而倒是WebAPI感觉更有前途,至少使用复杂程度和Flask、SpringBoot在一个水平线。

说到底吧,RPC协议和框架,其最终用户就是开发。
一开始能解决用户需求就行,没有其他替代方案,能解决问题,开发前辈们就很开心。
但用着用着,开发感觉体验太差了,就会有新一代产品出来,替代掉之前的产品。
而且越是新的协议,就不能有大的学习成本,容易上手,功能强大。
不信的话,你看下新的手机,比30年前功能多了不知道多少,但哪里还要一本厚厚的说明书才能上手呢?

REST的成功
REST的成功很大程度上源于HTTP及JSON使用的广泛性,其资源的思维确实很巧妙。

但其实不少REST落地成了HTTP协议收发JSON,直接把“HTTP方法”变成了JSON中的一个KV,进行了扩展;而且进一步封装了HTTP的返回值,将HTTP400/500,封装成了JSON,从而可以反馈更多的信息。换句话说,REST的一些问题,可以通过适当的灵活来解决。但唯独“传输效率”这个问题无法突破HTTP+JSON的极限。

个人认为,微服务之间内部通讯使用RPC提升传输效率,Web及外部通讯使用REST或HTTP+JSON可能是一个比较好的折中性选择。

其他通讯手段
很多啊,天天用。通过操作系统机制(共享内存、发送消息通知、粘贴板、各类内核对象等)、数据库(关系型、非关系型、列数据库),通过中间件(队列,Kafka,ESB),通过缓存,通过文件存储(NAS、NFS、对象存储)、通过UDP/RAW协议、通过网络广播、通过短信、通过邮件、通过自动拨电话、通过平台消息推送。

当然还有很多其他的方式,通过电信号编码,光信号编码、通过声波编码、通过量子通讯、甚至通过存储运输等等等等。

各类系统架构演化

一、整体趋势
天下大势,分久必合合久必分。复杂有复杂的代价,简单有简单的代价。

看这些年的发展,也能看出一定的端倪:
单体应用【一统天下】-》业务复杂后,应用拆分【应用拆分】-》SOA、ESB【接口拆分聚合】-》微服务【服务拆分】-》中台【业务聚合】-》去中台【业务不要瞎聚合,再拆回去】

微服务的简单,其实是将服务功能单一化,确实降低了编码及编码维护难度,也是有很高的代价的。我们不仅要享受简单,也要知道其代价。最直观的几个代价有:
1、需要很高的代价去打造适合自己的微服务治理体系
2、由于需要解决单点问题,每个服务要部署多个实例即使用量达不到也要备着
3、运维复杂度上升,需要工具支持,对人员要求也更高;
4、微服务的调用链,比单体应用的调用链,复杂,效率低,排错难;
使用微服务,对运维能力是有一定要求的,而且非所有软件都应该走微服务的路子。盲目的微服务化,服务拆分过细的结果,往往是又合了回来。

究其原因,人对复杂事务的掌握是很有局限性的,所以我们倾向于将复杂问题分解为简单问题,将问题标准化,然后解决问题。整个人类社会都是这样,才会有社会专业分工。但分工又不能太细,这样才能恰到好处的发挥人的创造力。最终都是多种因素折中的结果。

无论是软件开发,还是CPU制造,还是工厂制造商品,还是粮食的生产,原理是相似的。

二、单体程序还是微服务
个人认为,以后的发展趋势是单体系统、微服务架构,会相互学习相互补足。

很多典型的单体系统如操作系统、数据库、中间件如MQ等,在内部设计时也会根据功能进行拆分模块,并不会全部放到一起实现,会尽力降低某一部分出错后导致的后果;同时在分布式环境下,也会给出自己不错的答案。

而微服务正相反,其本身确实是降低了开放的难度,提升了开放效率,隔离做的很好。但同时要看到,微服务将不少工作扔给了运维,没有强力的运维,微服务拆的越细,最后死的也是越难看。所以在微服务化的过程中,很多项目都是拆细了又合并回来,接受了单体组建的风险,避免了运维工作的指数型增长。

单体程序的问题在于,单体应用如果太复杂了,人是很难考虑到各个环节的,需要用更复杂的手段,来进行保证,如火箭、飞机、航母,这些复杂的软硬件一体的开放工作,需要额外的系统及理论及代价去确保系统的可靠性。而且单体系统最长见的一个问题就是,单体系统的稳定性,小于单体系统中最差部分的稳定性,在很多没有良好管控的软件项目上,单体系统的稳定性,其实就是最差的那段代码决定的。人员水平不足,项目经验不足,人力不足,时间不足,是不是和你的项目很像?这种情况下,复杂的单体系统难以高效稳定的发展。

微服务,通过各种拆分隔离解决的这个问题,但同时在运维的维度引入了新的复杂度。每个项目都应该在单体服务稳定性与运维复杂度、资源耗费之间,取得一个平衡。孰优孰劣,应该按项目来确定,而不是一棍子打死。

此外,单片机给人的感觉是单体吧,但加个设备网关,搞个IoT不香么?

同样,各种复杂的操作,云平台给你封装好了,应用只需要找平台要这要那,对于应用来说,平台把内部实现封成了黑盒子,一定意义上说不是单体么?

三、SOA为何衰败

SOA的想做的事情,方向是对的,到今天,很多思想都在落地。

但那种“干这种改变世界的事情,老子要发明一套让所有人看起来都高大上的技术才行”的想法,让SOA过于复杂。

反而不如务实,用尽了少的代价让想法落地。

不应该为了解决简单的问题,一开始就弄一巨复杂的规范,SOA如此,EJB也是如此。

重点没有去解决问题,而是为了规范而去制定规范。甚至为了制定规范,还要发明一堆名词,发明一种语言。

比如说,SOA什么都要管理,就需要发明WSDL来框定业务。WSDL根本就不是人类容易看懂的,而且十分严格。如果通讯双方namespace有个字母大小写不一致,通讯就失败,报错根本看不懂。查几个小时,发现就一个字母大小写问题。问题是你只想发个字符串过去啊。

成功的规范,往往是先落地用起来,然后一点一点长大的;先出一套巨复杂的规范,然后回去套业务,得到的不是惊喜,往往是惊吓。

四、微服务和DevOPS
一个微服务团队,从头到尾完全管理好自己的服务,其实是很难的一件事情。实际中,不少团队,微服务的技术用了不少,但DevOPS其实都没算做起来,仍然十分的依赖运维团队来完成很多工作,自建的微服务平台也不够好用,有了问题人仰马翻的。

感觉这个阶段,不如直接花钱买云厂商的服务,规避部分技术风险,重点发展业务,会更好一些。等有些技术积累了,再做适合自己的技术解决方案。

五、今天的云原生还有哪些主要矛盾,下一次软件架构的进化将会主要解决什么问题?

个人认为,当前的架构,还远远没有达到最优状态。真正最优的时候,绝大多数开发人员,是不需要知道K8S、ISTIO、Spring、数据库、缓存及各类中间件的存在的。

之前的状态是,硬件按硬件的思路发展,系统及虚拟化按其思路发展,应用架构也是按自己的思路发展。之所以当前需要发明很多新技术,是硬件、系统及虚拟化、应用架构彼此之间都有一条鸿沟,那大家就都需要自己造轮子搭梯子解决问题,统一问题必然有N中解法。后面相互磨合久了,鸿沟会进一步变窄,直至平滑过渡。

应用层开发人员,会在很大的技术视野内专注于业务层,其他层的需求只需要简单调用服务即可。

但不久的将来,一定会面临新的巨坑,需要填。

六、FAAS趋势

个人对FAAS有种直觉上的偏见,感觉有些走向了另一个极端:
1、如果保持F很简单,那平台确实可以直接将功能封装为通用服务,但就算加上DSL,F可以施展的空间感觉也不大
2、如果让F变复杂,支持复杂业务,那FAAS其实就退化成为了功能十分单一的微服务,还不如直接微服务来的爽快
整体感觉就是有些鸡肋,一边有纯图形化工具或标准服务,一边是正常程度的编码,夹在中间。

这个真的很像当年ESB的思维方式,给了一堆的标准组件,给人一看感觉封装的真好,不用编程也能做好多事情啊。但用过就知道,稍微复杂的业务就要自己去扩展组件了,不会编程什么都做不了。最后就是换了一个技术平台写代码而已。

各种类型的调度

硬件层面:
1、操作系统管理进程,分配CPU、内存等资源
2、计算线程与CPU的绑定,也算一种调度吧

网络层面:
1、路由器交换机的配置、包括F5的配置
2、服务器或虚拟机组成Cluster或NLB
3、Nginx反向代理时不同节点分配不同的比重,加上访问策略,也算一种调度吧。
4、类似的Dubbo等框架,也支持不同的调度方式

任务层面:
1、做大数据处理的时候,接触过Yarn
2、Kubernetes中Pod调度及驱逐机制
3、线程池、socket连接池、DB连接池、对象池之类的管理好像也能算

此外,在调度的过程中,有一个规律,那就是调度的时候,大家都倾向于,将代码和数据放到一起进行。
在数据量小的时候,大家倾向于把数据搬运到代码附近,比如CPU的调度。
但数据量大的时候,尤其是到了大数据、云计算时代,我们反而倾向于,把代码搬运到数据附近,因为这样更合算。