由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - vertx里面同一个module多个verticle的疑问
相关主题
nodejs cluster和vert.x比较怎么样?写thread safe程序现在也是程序员必须要掌握的了吧
关于vertx和zhaoce大牛们说说为什么我那么钟意node?
多线程,异步,并发冲突,fp和其它Using Spring in Vert.x
go这么屌?parallel programming的复杂性分层/流行工具技术名词
问一个vertx的问题cassandra 的插入性能问题 (转载)
Node做大系统better than Java, .NETgo几天的一些感受
如何快速处理大量网上xml文件?有什么web server 可以后台接actor
vert.x 3预计月底发布beta1版本coroutine comes to Java - Project Loom
相关话题的讨论汇总
话题: verticle话题: thread话题: 异步话题: 启动话题: handler
进入Programming版参与讨论
1 (共1页)
f*****w
发帖数: 2602
1
看了文档和尝试了一些简单例子之后有些基本了解了。目前的理解是每个功能的模块都
应该是一个verticle,但是具体操作的building block应该都是Handler。 但是基于这
个理解又有些疑问
第一个问题是 文档里面说而一个module 里面实际上可以有多个verticle,并且互相
之间可以通信。但是文档里面对于如何同时启动多个verticle或者如何对于verticle寻
址通信只字未提。 是还有什么其他文档我没有看到吗 还是说verticle和handler是两
个完全可以互相取代的概念,所有对handler可以做的操作同样也可以对verticle操作?
第二个问题是 我不明白系统什么时候做并行操作。比如 我在同一个verticle里面监听
了10个端口,每个不同的端口是个不同的REST服务。这种情况下是不是意味着这10个服
务完全就没有可能被并行了 (因为每个verticle都是单线程的)。那这也就意味着对
于REST服务来讲,最优的做法应该是每个服务都运行自己独立的verticle ? 我这麽想
对吗
z****e
发帖数: 54598
2
verticle是抽象的概念,module是具体的文件
verticle是每次运行的时候,vert.x保证每一个verticle的instance会被单个thread所
访问
不会被多个thread同时访问,而module是你把文件打成的包叫做module
所以可以把多个verticle放到同一个module下面去
但是vert.x运行的时候,还是会将每一个verticle的instance安排给一个具体的thread
vert.x默认是你有多少个core,就运行多少个threads
这样你就不需要像node一样启动多个process了
这些threads之间的通信通过bus来通信
z****e
发帖数: 54598
3
系统什么时候并行你不需要操心
反正你的每一个verticle对象只会被一个thread所执行,在同一个时间点内
不会互相干扰,所以你不用去管vert.x什么时候做并行操作,什么时候不做
这个dispatch由vert.x来搞
所以哪怕你启动的只有一个verticle,只监听一个port
也还是会有多个threads来调用这个verticle的instances,java里面就是内存对象
然后当并发量大的时候,thread就会多起来
然后不同的threads如果调用同一个verticle
那么他们会分别持有这个verticle的不同instances
每一个thread分配一个instance酱紫
你就当你写的verticle是运行在单线程环境中就好了,并行的事,vert.x会帮你搞定
当然一个重要前提就是,你不能直接share object between threads
如果需要在不同threads中分享数据,则你需要看用bus
另外我记得他们好像提供了一个内存共享的map好像,你要自己查查
z****e
发帖数: 54598
4
如果你对vert.x怎么实现并行感兴趣
看event loop这一部分以及concurrency里面有说
http://vertx.io/manual.html#event-loops
不过你可以不看
z****e
发帖数: 54598
5
vert.x其实就是object或者说是verticle层面的封装
这样你就不用像fp一样搞什么immutable了
轻松容易许多,当然你要搞也可以,只是木有必要
记住这句话
"Vert.x guarantees that a particular verticle instance is never executed by
more than one thread concurrently."
http://vertx.io/manual.html#concurrency
z****e
发帖数: 54598
6
举个例子
class A
A有个对象是a
如果你啥都没做的话
那么这个a并不是线程安全的
为了线程安全,人们想出了各种方法
比如一种线程安全的机制就是lock
但是lock会带来各种狗血问题,比如死锁
而另外一种机制就是immutable
每个thread访问时候,拷贝一份副本就是了
但是这也会带来各种问题,而且不利于理解
fp的狂徒居然发疯了一样要求人们接受什么都是常量的想法
神经病
然后spring什么则是不做控制,你自己要留意
这样就加重了你写代码时候的负担,等于什么都没有做
然后node干脆就干掉多线程,用单线程来做
多线程启动多个process,但是这样的话
你自己要去管理process,以发挥最大机能
尤其是多个cpu多个core的环境下,也麻烦
然后ejb说我可以保证每个instance,一次只会被一个thread所访问
就木有问题,但是这样并发量大的时候,有些操作会导致thread堵塞
就是同步操作,所以ejb并没有很好滴address大并发的问题
虽然提出的构想和目标很美好,但是实现的手段不够好
很多人还是选择了spring那些
但是有了异步之后,大量block的操作被做成异步的
那这样就不会block鸟,然后此时再在object level做封装
就可以有效滴回避以上的各种问题
使得多线程开发更为简单,高效
vert.x就是这么一个东西,vert.x下写代码很容易
既不用immutable,也不用什么synchronized关键字
你只需要死死记住,每一个verticle的instance/java里面就是Verticle对象
不会,永远不会 被多个threads同时访问,就可以了
f*****w
发帖数: 2602
7
非常感谢这麽详细地解释了这些概念 我再消化一下 :-)
那第一个问题呢? 我对handler 和 verticle 之间的关系也很困惑。原因是因为我在
试图自己弄个toy example,里面主verticle会去deploy多个子verticle。 文档讲得很
模糊,我自己找到的API是 container.depolyVerticle() 但是这个函数take的
类型居然是handler! 这样让我不太明白我在根据需求设计自己的verticle/handler的
时候应该让他们遵从什么原则
l*******o
发帖数: 250
8
如果两个vert.x
读写同一个table呢? 还是需要保证同步?
f*****w
发帖数: 2602
9
我觉得这个不用担心 jdbc会处理好

【在 l*******o 的大作中提到】
: 如果两个vert.x
: 读写同一个table呢? 还是需要保证同步?

l*******o
发帖数: 250
10
@zhaoce, 不用担心transaction?
相关主题
Node做大系统better than Java, .NET写thread safe程序现在也是程序员必须要掌握的了吧
如何快速处理大量网上xml文件?大牛们说说为什么我那么钟意node?
vert.x 3预计月底发布beta1版本Using Spring in Vert.x
进入Programming版参与讨论
z****e
发帖数: 54598
11
启动两个process的?
只有node才会要求你启动多个process
其他无论akka还是vert.x,ejb, spring etc.
都不会做这种要求
启动一个process
读写table的lock是db要处理的问题
所以这里有可能blocked,这就是为啥我们需要worker
这个worker跟node的worker是一样的

【在 l*******o 的大作中提到】
: 如果两个vert.x
: 读写同一个table呢? 还是需要保证同步?

z****e
发帖数: 54598
12
之所以这么做
是因为你启动的是一个main函数
which一定会挂靠在某一个verticle下
你也知道,一个process只能启动一个main啊
你不能启动多个main吧?
对吧?无论啥语言,都只能有一个main入口,一个process的话
但是你写的verticle每个都有一个main
那你不可能用命令行把他们挨个启动,那样就成multi process了
我们要做的是multi thread,而非process
所以把deployverticle的东西用程序语言来实现,这里其实我用的是python
然后你启动了这个verticle之后,这个verticle会依次去部署那些verticles
酱紫同一个process其实运行多个threads,which不需要你操心的
如果你启动了多个process的话,之间的协调是很蛋疼的一件事
vert.x把thread的communication都做好了,有bus
如果是单线程的process,启动多个的话,你要自己去找bus,然后安装
调试,测试,一堆事,烦死
至于handler,这个是程序员的一个约定俗成的名称
一般涌来搞一个具体的event,会有一个event handler
所以当你在verticle里面监听了一个port之后
当这个port接收到了event,就会自动调用相关的handler去处理
所谓的handler就是这个意思,handler和verticle本质上是两个概念
你可以认为是两个不同的interface,任何一个class都可以impl零到多个interfaces
大概就这个意思

【在 f*****w 的大作中提到】
: 非常感谢这麽详细地解释了这些概念 我再消化一下 :-)
: 那第一个问题呢? 我对handler 和 verticle 之间的关系也很困惑。原因是因为我在
: 试图自己弄个toy example,里面主verticle会去deploy多个子verticle。 文档讲得很
: 模糊,我自己找到的API是 container.depolyVerticle() 但是这个函数take的
: 类型居然是handler! 这样让我不太明白我在根据需求设计自己的verticle/handler的
: 时候应该让他们遵从什么原则

z****e
发帖数: 54598
13
用vert.x跟其他一样,切记部署时候一台虚拟机/真实机器
就启动一次vert.x的instance就好了
只有单线程的process instance需要启动多次
其他无论是fp的akka, play还是oop的ejb, spring这些
都没有说一个虚拟机启动多个instances的道理
一般就是一个虚拟机启动一个instance,搞定
node是奇芭的存在
然后一般多线程的框架,都会自动管理threads
让你从无聊而又繁琐的并发冲突中摆脱出来
写代码就不要各种lock, synchronised这些鸟
当然为了实现这个目的,会有这样那样的要求
比如要immutable,vert.x是所有多线程框架中,要求最低的一个
其他要求都很恶心
z****e
发帖数: 54598
14
container.deployVerticle("foo.ChildVerticle", new AsyncResultHandler
() {
public void handle(AsyncResult asyncResult) {
if (asyncResult.succeeded()) {
System.out.println("The verticle has been deployed, deployment
ID is " + asyncResult.result());
} else {
asyncResult.cause().printStackTrace();
}
}
});
你说的是这种吧?
这个其实不是,verticle的名字放在第一个参数里面,也就是那个foo.ChildVerticle
这个才是verticle,后面那个handler是异步时候需要做的,其实就是一个lambda
文档为了向后兼容,所以用老的方式写,如果是java8的话,会很简洁
就是把一个func塞入这个verticle做callback,一旦这个verticle被deploy完毕之后
就会调用这个callback func
我在javadoc上看到deployverticle的参数应该是一个string
你把你的verticle名字写进去就好了,verticle参数用json
deployVerticle(java.lang.String main)
Deploy a verticle programmatically
z****e
发帖数: 54598
15
实话说,handler这个部分用fp会比较容易搞
也就是callback,异步这些概念,理解下再弄比较好
很开就会遇到callback hell,那一层层的金字塔
rxjava就是你要找的救星
z****e
发帖数: 54598
16
会blocked,交给worker verticle就好了

【在 f*****w 的大作中提到】
: 我觉得这个不用担心 jdbc会处理好
h********4
发帖数: 51
17
根据你的总结,可不可以理解为vertx和ejb都提供一个instance一个thread的保证,但
是vertx更侧重于异步,ejb更侧重于同步(一个request对应一个thread)?

【在 z****e 的大作中提到】
: 举个例子
: class A
: A有个对象是a
: 如果你啥都没做的话
: 那么这个a并不是线程安全的
: 为了线程安全,人们想出了各种方法
: 比如一种线程安全的机制就是lock
: 但是lock会带来各种狗血问题,比如死锁
: 而另外一种机制就是immutable
: 每个thread访问时候,拷贝一份副本就是了

z****e
发帖数: 54598
18
是的,你的理解非常准确
其实所有的多线程框架都提供了一种机制解决冲突问题
因为lock&synchronised的确是很难搞
让用户不再需要去写这些东西是这些框架的目的
vert.x除了worker以外的verticle都是异步的,或者说都需要做成异步的
同步会block线程
ejb当初设计时候没有考虑到异步的情况
因为毕竟年代已经有些久远了,所以大多数操作都还是同步的
但是以后不知道,以后这个情况可能会发生改变
另外一个request未必对应一个thread,看设计
到了具体的instance,可能是多个对应一个,或者一个request调用多个instance
但是在同一个时间点内,一个线程只会调用一个instance
保证其他threads不会过来搞
异步的设计跟同步的架构设计有明显区别,同步是一个request启动一个thread
但是异步不是,异步是有多少个cpu的core,启动多少个thread
然后把event pool里面的events分配给这些threads
这个是vert.x,node是只有一个thread去轮询event pool
所以会启动多process,其他框架都不这么做
了解这个差异很重要,因为这个决定了能否scale
同步一个req启动一个thread一旦并发数量上去
就有可能受限,但是异步的设计不会受限,比较容易scale
其实异步最大的优势就是比较容易发挥机能,让cpu满负荷运转
node只让其中一个core满负荷,而vert.x则让整台机器的cpu的所有core全部满载
这样就几乎把这台机器的机能发挥到了极限,再怎么剥削也难剥削出其他东西了
如果还不够用,那就是需要添加机器的问题了,不是软件能够做的了

【在 h********4 的大作中提到】
: 根据你的总结,可不可以理解为vertx和ejb都提供一个instance一个thread的保证,但
: 是vertx更侧重于异步,ejb更侧重于同步(一个request对应一个thread)?

f*****w
发帖数: 2602
19
晕 确实是的。 读文档会错意了 ;-D
非常感谢哈~~

String>

【在 z****e 的大作中提到】
: container.deployVerticle("foo.ChildVerticle", new AsyncResultHandler
: () {
: public void handle(AsyncResult asyncResult) {
: if (asyncResult.succeeded()) {
: System.out.println("The verticle has been deployed, deployment
: ID is " + asyncResult.result());
: } else {
: asyncResult.cause().printStackTrace();
: }
: }

f*****w
发帖数: 2602
20
请问那么JDBC的连接池呢 在vertx下如何才能最优化jdbc的并发?
能不能指教下我这麽做对不对
假设我有三个数据库操作 增删改。 我把每个数据库操作的模块 M(每个模块包括了
所有可能的数据库操作 ),设置成worker 。 我打算起10个thread的话,我就把M 启
动10个instance,每个instance都维持各自的一个数据库连接,并且监听同一个vertx
地址 K。 然后如果其他web service需要操作数据库的时候就发送相应的JSON object
到K。(也就是说JSON object需要能完整描述我需要做的数据操作是什么)
这样是不是听上去有点stupid? 因为本来可以调用一个函数解决的问题需要先encode
成JSON,然后在模块M里面还要理解JSON 并作相应的操作。 有没有大家已经比较常用
的更好的pattern?

【在 z****e 的大作中提到】
: 系统什么时候并行你不需要操心
: 反正你的每一个verticle对象只会被一个thread所执行,在同一个时间点内
: 不会互相干扰,所以你不用去管vert.x什么时候做并行操作,什么时候不做
: 这个dispatch由vert.x来搞
: 所以哪怕你启动的只有一个verticle,只监听一个port
: 也还是会有多个threads来调用这个verticle的instances,java里面就是内存对象
: 然后当并发量大的时候,thread就会多起来
: 然后不同的threads如果调用同一个verticle
: 那么他们会分别持有这个verticle的不同instances
: 每一个thread分配一个instance酱紫

相关主题
parallel programming的复杂性分层/流行工具技术名词有什么web server 可以后台接actor
cassandra 的插入性能问题 (转载)coroutine comes to Java - Project Loom
go几天的一些感受关于clojure
进入Programming版参与讨论
z****e
发帖数: 54598
21
因为现有的数据库操作会blocked
如果你不用worker的话,你整个thread会被blocked住
这样就跟tomcat什么没有区别了
所以需要用上worker,然后释放启动操作的thread
这么做目的就只有一个,释放当前线程,否则就会被blocked住
你不需要启动10个worker instance,也就是10个worker thread
因为数据库连接是有线程数量访问上限的,如果一万个thread同时启动的话
db也只能host那么有限的几个,比如设置了访问上限是100个
那么一万个就只能100个100个地访问,一定要排队
你可以在worker里面启动一个线程pool,然后设置连接池这些
目前数据库访问都不是异步的,没有那么傻瓜的做法
这么做目的就是把同步搞成异步,无它,要么就干脆不用,换nosql
但是trade off就是各种文档欠缺同时没有transaction, index这些的支持
well,也不是完全没有,但是明显会少很多,相对db而言
要么就干脆同步,同步的话写起来就很简单,怎么做就怎么写
但是同步也还是需要搞连接池这些,只不过简单很多,因为文档有很多
这么做stupid原因也很简单,db的异步操作目前还不成熟
当然你也可以尝试着用rxjava-jdbc,这个还没正式release
总之怎么做都比较折腾,没有绝对傻瓜的解决方案
无非以下几种解决方案
1)做成同步的,tradeoff就是并发时候这里会明显blocked,当然少量的并发感觉不出来
2)做成异步的,你需要启动worker,然后自己管理connection pool,tradeoff就是自
己要动手
3)用rxjava-jdbc,tradeoff就是版本还不成熟,但是写起来容易点
4)丢掉db,换nosql,比如mongo什么的,但是文档相对偏少,而且transaction社么都
不怎么支持
5)干脆丢掉vert.x这些异步框架,直接上tomcat/servlet,这样db操作就都是同步的了
选一种
以前stream84那个家伙的blog还在,最近github有问题,我只找到xml版的blog
https://github.com/stream1984/stream1984.github.io/blob/master/atom.xml
上面写了一个例子很好滴说明了异步和同步在书写代码上的差异
用异步会使得一些原来同步时候很容易的事变得复杂起来
所以异步很多时候不用db

vertx
object
encode

【在 f*****w 的大作中提到】
: 请问那么JDBC的连接池呢 在vertx下如何才能最优化jdbc的并发?
: 能不能指教下我这麽做对不对
: 假设我有三个数据库操作 增删改。 我把每个数据库操作的模块 M(每个模块包括了
: 所有可能的数据库操作 ),设置成worker 。 我打算起10个thread的话,我就把M 启
: 动10个instance,每个instance都维持各自的一个数据库连接,并且监听同一个vertx
: 地址 K。 然后如果其他web service需要操作数据库的时候就发送相应的JSON object
: 到K。(也就是说JSON object需要能完整描述我需要做的数据操作是什么)
: 这样是不是听上去有点stupid? 因为本来可以调用一个函数解决的问题需要先encode
: 成JSON,然后在模块M里面还要理解JSON 并作相应的操作。 有没有大家已经比较常用
: 的更好的pattern?

z****e
发帖数: 54598
22
你可以用一个worker instance来维护一个connection pool
然后你自己再在worker里面维护一个thread pool,对应着connection pool
然后再将每一个发过来的msg parse后轮放到thread pool里面去处理
自己写要解决异步问题就这么麻烦,或者用其他人的mod
但是用了别人的mod,你还是会遇到文档的问题
还不如自己写,至少明白是怎么回事,parse json是必需的
因为msg里面的数据结构跟db里面的数据结构是不一样的
如果不转换的话,db无法接受json,nosql就大部分都是用json来储存数据
所以接受json,说到底这个是db的规范条条框框比较多造成的
数据结构在网络中,内存中和硬盘上都不一样,显然需要转换

vertx
object
encode

【在 f*****w 的大作中提到】
: 请问那么JDBC的连接池呢 在vertx下如何才能最优化jdbc的并发?
: 能不能指教下我这麽做对不对
: 假设我有三个数据库操作 增删改。 我把每个数据库操作的模块 M(每个模块包括了
: 所有可能的数据库操作 ),设置成worker 。 我打算起10个thread的话,我就把M 启
: 动10个instance,每个instance都维持各自的一个数据库连接,并且监听同一个vertx
: 地址 K。 然后如果其他web service需要操作数据库的时候就发送相应的JSON object
: 到K。(也就是说JSON object需要能完整描述我需要做的数据操作是什么)
: 这样是不是听上去有点stupid? 因为本来可以调用一个函数解决的问题需要先encode
: 成JSON,然后在模块M里面还要理解JSON 并作相应的操作。 有没有大家已经比较常用
: 的更好的pattern?

z****e
发帖数: 54598
23
如果是mysql或者postgresql的话
看看这个mod,这个是vert.x里面scala lan作者写的
应该还不错,不过我没用过
https://github.com/vert-x/mod-mysql-postgresql
但是还是没有成熟,也同样会有文档的问题
没办法,这就是现状,现状决定了基建还不完善
所以折腾是必不可少的
f*****w
发帖数: 2602
24
非常感谢 既然我已有的大致思路是对的那我就折腾下试试看

【在 z****e 的大作中提到】
: 因为现有的数据库操作会blocked
: 如果你不用worker的话,你整个thread会被blocked住
: 这样就跟tomcat什么没有区别了
: 所以需要用上worker,然后释放启动操作的thread
: 这么做目的就只有一个,释放当前线程,否则就会被blocked住
: 你不需要启动10个worker instance,也就是10个worker thread
: 因为数据库连接是有线程数量访问上限的,如果一万个thread同时启动的话
: db也只能host那么有限的几个,比如设置了访问上限是100个
: 那么一万个就只能100个100个地访问,一定要排队
: 你可以在worker里面启动一个线程pool,然后设置连接池这些

1 (共1页)
进入Programming版参与讨论
相关主题
coroutine comes to Java - Project Loom问一个vertx的问题
关于clojureNode做大系统better than Java, .NET
express.js的作者弃node转投go如何快速处理大量网上xml文件?
node.js不可放弃vert.x 3预计月底发布beta1版本
nodejs cluster和vert.x比较怎么样?写thread safe程序现在也是程序员必须要掌握的了吧
关于vertx和zhaoce大牛们说说为什么我那么钟意node?
多线程,异步,并发冲突,fp和其它Using Spring in Vert.x
go这么屌?parallel programming的复杂性分层/流行工具技术名词
相关话题的讨论汇总
话题: verticle话题: thread话题: 异步话题: 启动话题: handler