经济学里面有一个名为“外部性“的概念。外部性是指一个人或企业的行为对其他人或企业产生的影响。
外部性可以是正的,也可以是负的。比如,一个企业的生产活动可能会产生污染,这就是一种负的外部性,对周围的环境和居民造成了伤害。相反,一个企业的生产活动也可能带来正面的外部性,比如提高周围地区的就业机会或改善周围地区的基础设施。
From Martin Fowler microservices:
微服务架构即是采用一组小服务来构建应用的方法。
每个服务运行在独立的进程中,不同服务通过一些轻量级交互机制来通信, 例如 RPC、HTTP 等。
服务围绕业务能力来构建,并依赖自动部署机制来独立部署。
From Sam Newman [Building Microservices]:
You should instead think of Microservices as a specific approach for SOA in the same way that XP or Scrum are specific approaches for Agile software development.
微服务即SOA的一种实现方式。企业服务总线(ESB)设计的失败给SOA带上了负面的标签。
最近在一个网站上,看到了很炫的网页特效:视频背景透明。该网址是:http://videostir.com/。他们还为用户提供了制作透明视频的服务。用户只需要上传他们要求的格式的视频,就可以生成一个透明的视频。
正如该网站所演示的,这种视频作为网站的引导,效果非常赞,互动的感觉非常强烈。
前面的文章《我理解的Smart Domain与DDD》中,我们分析了 Smart Domain 的设计,尝试回答了为什么 Smart Domain 可以用于实现 DDD,并对Smart Domain和DDD进行了一些扩展性的讨论。
虽然 Smart Domain 作为一种设计范式,可以辅助我们实现 DDD。但是具体到真实项目中,建模这个过程还得结合实际的领域问题,深入思考,大量尝试,大声建模,才能得到好的模型。有哪些值得参考的案例呢?下面分享几个个人在项目中觉得还不错的建模实践。
新的一期技术雷达如期发布,仔细阅读了这一期的所有条目,CUPID这一条尤其让我产生共鸣。
CUPID出自Daniel的一篇名为《CUPID—for joyful coding》的博文,即《CUPID-为了快乐编程》。CUPID是Composable/Unix philosophy/Predictable/Idiomatic/Domain based几个单词的缩写,有经验的同学一看就知道这是好代码的一些属性。知道Cupid这个单词的同学还能感受到这一组属性所蕴含的对于软件工程的热情。Cupid的中文是丘比特,是指古罗马的爱神,其意象是一个长有翅膀的小孩,拿着弓箭射向人们,以便人们可以相互爱上对方。
作为一个非专业c/c++
开发人员,相信很多人跟我一样,常常会在跟c/c++
打交道时碰到困难。然而,我们所使用的很多底层的库或软件,却有大量是用c/c++
编写而成。所以,了解一些基本的c/c++
知识对于非专业c/c++
开发人员将非常有帮助。
在下面这些典型的场景中,我们可能会需要用到这些知识:
c/c++
项目c/c++
程序里面进行少量的c/c++
开发,并与c/c++
代码交互本文尝试总结一下基本的c/c++
知识,包括常见的平台、静态库/动态库的原理、基础编译指令等。并将结合一些实例来加深理解。
在前面的文章中提到我们在一个高性能场景中尝试了rust
,那么它的效果如何呢?
在这次rust
的尝试中,我们实现了一个通用的特征数据处理框架,并实现了几个常用的算子。这个数据处理框架目标是实现 Spark ML pipeline
的在线计算,为机器学习模型的在线推理场景提供特征处理。
我们选用了两个rust
的grpc
框架对外提供服务。它们分别是grpc
和tonic
,前者是基于线程池的实现,后者是基于rust异步模式async/await
的实现。实验过程发现两者性能相差不大,tonic
稍好,快2ms
左右(不到5%),这可能是由于其数据结构设计更为精简带来的。
为了更有参考性,我们直接进行端到端的测试(用grpc
客户端发起请求,在客户端采集数据),并与scala
版本的实现进行性能对比。下面的结果中,服务端应用均部署在同一台64核心
+32GB内存
的服务器上,客户端也在此服务器上发起请求。由于数据处理的逻辑一致,客户端使用同一个java
版本的实现。
在最近的一个客户项目上,为了做性能优化,我们花了大量的时间,然而最终结果还是不够理想。我们的场景是实现特征处理过程和机器学习模型线上推理服务。由于用户量巨大,我们需要做到2万的TPS,每个请求需要在30ms内返回,且每个请求中包括对1000个项目的处理过程。
我们所使用的技术栈是spring
和grpc
。在经过极致的代码优化及内存调优之后,运行在一台32GB
内存64核
CPU的服务器上,我们发现90%
的请求可以在25ms
完成。但是如果观察99%
的分位线时,响应时间就下降到了70ms
,有时候还可能超过100ms
。
为什么会出现上面这么明显的波动呢?问题出在java
的gc
上。其实对于gc
,我们已经非常仔细的做过调优了,整个过程没有full gc
的发生。然而,在持续的压力测试下,java
的young gc
却在频繁的工作。由于处理的数据量过大,新生代的gc
几乎每秒都会触发一次,每次释放5GB
内存,耗时30ms
左后。
我时常在项目中听到一些经验稍欠缺的开发人员在Code Review时这么讲:
这里为了方便测试我抽取了一个纯函数,这个函数包含了主要的业务逻辑,测试覆盖率也比较高,我们可以认为这一部分质量不错。
使用这个函数的地方由于集成度高不好测试,我们就不做自动化测试了。
他的代码可能写成下面这样:
1 | // some_file.ts |