系统设计与构架群社群活动

加微信ID onetptp 好友注明加系统设计群

有奖征文活动

奖金是 0.1 个 ETH / 文章,如果有多个人发的话,把奖金一分为三,第一名取其二,第二名取其一

https://github.com/puncsky/system-design-and-architecture/issues

已经结束的往期有奖征文

运营准则

  1. 问/答/分享。欢迎问问题、回答问题、分享知识。推广可以有,非原创可以有,但是必须要切题,质量要高。问问题之前先学习如何问问题。
  2. 主观高于客观。客观的知识你总能搜索到,所以我们更看重你个人的实际体验和感受。注重速成,一句话的精妙解释优于一本书的故弄玄虚。
  3. 7:3 的信噪比。希望我们的讨论既有用又有趣 —— 7:3 是个不错的比例。

讨论精选

Natee

想实现一个模式,对后端服务的 login 请求经过网关层的基础验证以后,转发给 ‘登陆服务器’,‘登陆服务器’在验证过request中的username&password之后将用户的部分信息,例如分组,权限以JWT存入token中,返回给客户,客户在后续请求中带上此token,随后在网关中解析token将payload里面的分组,权限信息解码放到header中,供后面服务模块调用。 但是我遇到一个问题,我使用的api网关KONG在解析token需要有iss,就是consumer,对应的consumer做成的jwt中有issuser,指明token是给谁用的,然而我在生成token时候是在登陆服务模块生成的,这样子的话,我在做token的时候就需要把iss写到payload中去,但是iss是在网关里配置consumer的jwt时候生成的key,这个key也可以指定,不指定的话随机生成。这样子就出现问题了,在登陆服务器验证时候一定要放入一个iss进jwt的payload,然而这个iss是在网关层生成的

这个要看你 jwt 具体的算法 algo ,你们 iss 到底是用不同的用户的不同的 key 签的,还是所有的 jwt 共享一个 iss。我的意思是,在对称加密algo 的情况下,不同用户有不同的 sub,但是 iss 是可以共享用一个 master key 签名的

这样只需要让登陆服务器和 api 网关共享一个 master key 就可以了

Jack

  1. 我想知道enterprise service bus,像Apache camel,是过时了吗? 是不是不符合Smart endpoints dumb channel?
  2. 还有event vs threads, 现在有个定论哪个好吗?还看到说akka, Haskell就是综合两者的优点,可以讨论一下

York

用java的akka写过一点点很简单的actor model的代码,在用debugger的时候还是看到下面起的还是 thread。个人觉得akka只是对thread进行封装,用actor model(event/message processing)的套路呈现给你一系列API用来处理concurrency。所以就event和thread而言,就看你的app对计算资源的控制需要多细的粒度。event更high level一些更接近业务逻辑。直接用thread的话,假设你实现的好overhead应该还是会比用akka要小吧

大小说家👻

同意,我们组用的scala akka stream,高度封装的akka actor, 仍然需要implicit的传入一个executionContext,(相当于Java的线程池)。返回future的时候,实际上是通过这个线程池新开了一个线程异步处理+call back。

写起来比多线程需要考虑的少一些,也安全一点,因为通过map, reduce 的stream处理方式避免了shared variable的使用

开发的时候能更关注于业务本身

Jack

谢谢分享,你的体验和这里说的一样: https://blog.acolyer.org/2014/12/12/scala-actors-unifying-thread-based-and-event-based-programming/ “Compared to a purely event-based approach, users are relieved from writing their own ad hoc thread pooling code. Since the internal thread pool can be global to the web application server, the thread pool controller can leverage more information for its decisions. Finally, accesses to an actor’s mailbox are race-free. Therefore, resources such as user profiles can be protected by modeling them as (thread-less) actors.” 真的是两种的好处都有。

我感觉 actor 应该等同于CSP (communicating sequential processes)里的 sequential process, 是用artibter做了serialization

这篇文章说events不好 https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-idea/ , 还不如threads, 作者包括Eric brewer, 他们发现除了pub-sub以外用threads又快(用系统的threads, 没有event loop的bottleneck),又容易写,又容易发现错误(stack, not heap),是不是说核心的components就应该用threads,还是说现在语言,操作系统,硬件等都进步了,这篇文章也过时了?

这个网站推荐用event driven/messaging based/async microservices,而不是synchronous restful microservices https://solace.com/blog/experience-awesomeness-event-driven-microservices/ https://solace.com/blog/achieving-microservices-flexibility-patterns/ 我觉得有点牵强,大家能不能看看,有没有可取的地方

Jack

架构师之路说“服务读写分离架构,绝不推荐” https://blog.csdn.net/z50L2O08e2u4afToR9A/article/details/78841727

solace 说:“What you do sacrifce with CQRS(读写分离) is consistency, but you enhance both performance and availability and, as mentioned earlier, embracing eventual consistency alleviates this concern for most use cases.”

Martin fowler 都说用cqrs要小心,一般都效果不好: https://martinfowler.com/bliki/CQRS.html

Such

https://juejin.im/post/5da2f8fee51d457849547305 golang的interface实现的理解

Tian

补充一下背景知识,并发模型大比拼

  • threading/multiprocessing, lock-based concurrency
    • protecting critical section vs. performance
  • Communicating Sequential Processes (CSP)
    • Golang or Clojure’s core.async.
    • process/thread passes data through channels.
  • Actor Model (AM): Elixir, Erlang, Scala
    • asynchronous by nature, and have location transparency that spans runtimes and machines - if you have a reference (Akka) or PID (Erlang) of an actor, you can message it.
    • powerful fault tolerance by organizing actors into a supervision hierarchy, and you can handle failures at its exact level of hierarchy.
  • Software Transactional Memory (STM): Clojure, Haskell
    • like MVCC: commit / abort / retry
  • Single threaded - Callbacks, Promises, Observables and async/await: JS

event driven/messaging based/async microservices vs. sync restful microservices 这个我觉得还是以业务需求为主要的决定因素,比如用户注册时的 fraud detection 必须实时做决定这个请求要不要block,必须是 sync 的;银行的支付系统就是特别的慢,十几秒用户等不起,那么只能够做成 async 的;大企业构架很混乱,为了解耦加入一个 message queue,把很多 n^2 的关系复杂度变成 1

CQRS 出现的主要原因是写比读成本高而且互联网服务的读写比大概 200:1,而我们想要优化吞吐量。具体实现上是做在服务层还是数据层要看情况。我在 Uber 见到的奇葩的情况:数据层主从数据库读写分离,上游是一个 monolithic API 层,再往上是一个超大的 Cache 层,再往上是 realtime api 层。

Facebook TAO 在我看来本质上也是读写分离,而这个分离跨越了主从 cache,数据库,还有跨区域的数据中心

所以说读写分离在数据层还是服务层做不是一个值得讨论的问题,因为数据也是一种服务,服务于具体的需求

Jack

https://www.oreilly.com/library/view/microservices-for-java/9781492038290/ch04.html

“Real applications could have dozens or even hundreds of microservices. A simple process like buying a book from an online store like Amazon can cause a client (your web browser or your mobile app) to use several other microservices. A client that has direct access to the microservice would have to locate and invoke them and handle any failures they caused itself. So, usually a better approach is to hide those services behind a new service layer. This aggregator service layer is known as an API gateway.”

"Apache Camel is an open source integration framework that is well suited to implementing API gateways. "

Adrianliu & 周宇超 & 低调 & Kai: idempotent key 在服务端还是客户端产生

请教个问题:如果想让整个 system idempotent, 比如payment system 防止duplicate pay, 一般来说是在client 发送请求时生成一个UUID 发给server,还是让server 去产生一个UUID给client,然后client 再发送request?

这个是2 phase commit吧?

不是。我的问题是防止客户端retry 导致duplicated request

我知道是防止duplicate这种事要从全局去避免。但是我现在主要在纠结客户端的duplicate request 那种情况

payment系统一般比这复杂,我明白你意思了,你相当于用UUID作为token唯一识别一次transaction

嗯嗯嗯对的对的

我们组之前做过类似的,是在server生成UUID

这样的弊端是不是多了一个round trip ,客户端拿到UUID,然后再发送真正的请求

感觉都可行,是取舍的问题,客户端生成UUID有什么弊端?不安全吗?

没想明白暂时。。

https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb

这篇我看了,感觉他说就是用一个library啥的

这篇文章还是没说那个idempotency key 哪里产生的

payment还是看uber的吧,气床毕竟不算高并发

这个重要么?如果数据库已经有了这个key就插不进去,如果没有那么就意味着可以

重不重要我不知道,只是想知道哪种比较好

嗯嗯那个看了。有个疑问,如果第三方Payment provider 失败了,这个时候我们把这个record 放到retry queue去,这样还能保证同一个user的多个request的order吗

Uber那个缺了个对账环节,就是有可能银行那边数据和uber这边数据不一致

怎么讲?每天对一次账这样么

自己根据数据量来定对账频率

cron job?

这个需要银行那边对完帐再发给我们系统,然后我们来对吧。

所以得依赖第三方的频率

这里是跟PSP对账还是银行?

总结:idempotent key 在服务端产生的好处是比较安全,坏处是多了一个 round trip; 因为格式是固定的,还可能是随机的,比如 UUID,那么客户端产生也可以,但是要注意检查这个 idempotent key 与 order ID 的联系,确保客户端不能够用之前已经成功的 order 支付的 idempotent key 算做最新的 order 的支付

王博睿: grpc + kinesis

请假大家一下。我如果想搭一个grpc和aws kinesis的服务,整个构架应该怎么弄呢?

整个服务很简单,只需要用户通过grpc的服务来访问读取kinesis的数据就好了

双双:请问下大家如何模拟分布式系统三个服务器统计一本书的字频,需要实现选举。慕清、大小说家、Elias、低调、=.=

想到了当年的 master slave, map reduce

我觉得主要还是解决一致性问题,可以通过paxos协议实现,保证选举。或者最近我有看区块链技术,也可以通过区块链的共识算法实现选举,这个是我个人想法。

插科打诨:一本书哪需要三台服务器😝

我们这个是作业,老师就让模拟下,说可以用paxos

可以考虑一下bully算法,实现简单,节点数少的时候还不错

这个群藏龙卧虎啊,感谢大家,我都看看[Whimper]

请问下大家实现整个系统的流程嘛,刚开始接触分布式系统,完全小白[Whimper]

主要是老师说要先选出leader,把任务分成一堆chunk,cluster里的各个server要处理不同的chunk,最后再汇总到leader那里,再传给client。这个过程我感觉就是MapReduce的过程。除了选leader和paxos一样。所以我不太清楚要在那里使用zookeeper。希望大佬们可以帮忙解惑一下

zookeeper就是用来解决选举的,如果使用paxos了 就不用管了

没要求用什么方法,就说要实现这个功能,举了个例子说paxos

还可以用pseudo random

区块链流行 PBFT, 我们公司在实现的时候用的 libp2p + PBFT

System Security: Natee

请问下,这个是要什么回答?

engineering security education (e.g. owasp top 10) + code review + product security review + bug bounty

@Natee 碰巧遇到一个答案 https://mp.weixin.qq.com/s/DtGLFwcwNMCZseOKOAOC9Q

如果这篇文章对你有帮助

在 Github 上 Follow 我 :)

下载 硅谷io App

使用我们的 Android App 接收最新的更新,用手机收藏和复习好文章

积分榜

普通讨论得 1 分,高质量的问题或答案得 10 分,积分每周六更新。

Rank
Name
Contribution
1Jack99
2Natee82
3=.=53
4🤔帕特里克星🦀50
5adrianliu33
6大聪战将32
7低调29
8慕清29
9双双28
10Tian Pan27
11Such24
12yifei23
13大小说家23
14openGPS.cn17
15周宇超15
16Boyang15
17Gary(小网熊)14
18York14
191点50分14
20如似井中月13
21外劳Tonito13
22@邹扒皮.com13
23陈子12
24Terence11
25milo_hollandlop11
26王博睿10
27Kirk张7
28谨言慎行5
29盆粥真的很轻啊😬5
30题材新颖5
31tp4
32姜景康4
33kourim4
34罗迪4
35墨翟3
36车少3
37metacpp3
38木易3
39Jack3
40kingauthur3
41doudou+201606192
42黄潇畅2
43Elias2
44焦加麟2
45Elias2
46Yuan2
472
48刘雪2
49知知🥗🦜🍋🍋2
50纳罕2
51Christiano Cai2
52SEAN2
53Bridge2
54惠秀宝2
55崔博武2
562
57Kai2
58Wintel2
59Tina1
60Hoooooo!1
61Dino1
62莫叽莫叽1
63Robotics_Qi1
64[email protected]1
651
66填坑侠1
67二两1
68fnqj1
69💮 ҈҉҈҉҈҉҈҉҈҉҈1
70🦱1
71PL1
72💭1
73Lucy1
74sweetweapen1
75道哥1
76Finn1
77王凡城1
78T海+天T1
79Novelidea1
801
81苗小杉1
82pekosan1
83易安 Yian1
84V1
85正阳1
86赤小豆1
87生如夏花1
88Shuai Yuan1
89SJ1
90Yanan(小叮咚)1
91孙煜征1
92王优豪1
93羽Fr1
94coding1
95404None1
96周载南Victor1
97顾天豪1
98小米1
99吴霖1
100炫酷的大高个1
101yw1
102sytrus1
103胡宗明1
104陈子平1
105汉堡包1
106Happy1
107Zero1
108XY达1
109.┧風ξ╀.1
110A火清1
111龚雪1
112厉亚伟1
113Yiting1
114haidong1
115肆伍1
116十四1
117似水流年1
118思想手1
119bert1
120王师虎_Karin1
121dreamy1
122吉吉1
123晓川1
124Wentao1
125彭安建1
126Sinan1
127周劲光1
128泥大猫1
129blank1
130keke今天刷题了吗1
131Raymond1
132朱恺康1
133Shuofei1
134Yilun.C1
135richard1
136Jipeng1
137Zhihe1
138子子子子钰1
139Christie1
140欧阳1
141Carrie1
142Roman豆1
143summer1
144Hot1
145田明远1
146Henn1
147Louis1
148Forever 杨1
149鄢程鹏1
150AugustRush1
151Liyun丽赟1
152戴维1
153K1
154Shenghua1
155不靠谱1
156皮皮钰1
157Tianchen Wang1
158Roland1
159chenxi1
160大棕熊zhliu1
161Liang1
162yjhbnb1
163Kanko🍋1
164Charles - XDH Financial1
165mike1
166積木1
167浮游生物1
168hbc1
169Jun1
170slf1
171Jimmy P.1
172Yjy1
173KUAN1
174漠北以北1
175Ezio1
176jyuan1
177NickLouie1
178yang1
179左岸1
180Samchen1
181Yingying1
182S1
183Helloworld1
184SH1
185Marshall-AP1
186nikoseven1
187Wang1
188Andrew1
189Super🍋Ariel1
© 2018 硅谷io
Built with ❤️ in San Francisco