成都创新互联网站制作重庆分公司

component的生命周期怎么理解

这篇文章主要介绍“component的生命周期怎么理解”,在日常操作中,相信很多人在component的生命周期怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”component的生命周期怎么理解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

在金林等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、做网站 网站设计制作定制网站制作,公司网站建设,企业网站建设,高端网站设计,成都全网营销,成都外贸网站制作,金林网站建设费用合理。

storm中的spout,bolt的生命周期,都是storm帮你管理好,你只要新建一个实例,指定该component的并行数,就可以。那么topology中所用到的工具类的生命周期该如何处理,例如数据库连接池、redis的连接池,这些对象该放在哪里初始化?本文以jdbc连接池为例,讨论此问题。阅读本文前请先自行了解storm topology的运行流程。

Storm Component的生命周期

storm component泛指topoloty中的spout、bolt,是spout和bolt的一个统称。而component生命周期,我结合storm作者nathanmarz大神的回答和自己的理解,描述一下:

1,当提交了topology后,spout、bolt的实例会在本地机器(执行storm submit所在的机器)上被创建,并且在本地序列化。另外,所有的component的构造函数、declareOutputFields方法都本地会运行一次。

2,整个topology被上传到nimbus上。

3,对应supervisor会向nimbus获取序列化后的topology代码,交给对应的worker执行。

4,每个worker执行如下:反序列化代码,运行对应component的prepare/open(初始化对应的component)。举个例子,某spout在topology中设置了3个并行度,且topology设置了3个worker,该open方法就会在3个不同的worker上分别调用1次,共调用3次。

5,worker通知executor不断循环去跑nextTuple/execute方法。

需要注意一点:component的初始化相关的操作应放在prepare/open方法中执行, 而不是在实例化component的时候进行或者topology的main函数。

Jdbc Pool 初始化方案

参考component的生命周期,能想到有两种方案:

1,每个component都维持一个与数据库的连接,此种方案适合于写操作非常频繁,component数目比较少,且中间不会有一段时间没有任何写、读操作,否则会发生MySQL connection timeout;另外可省去从连接池获取连接,用完连接后返回给连接池这两步操作。如果确定这种方案,则只要将数据库的配置放到config中,在对应的component中初始化数据库连接即可。

2,在每worker中维持一个连接池,worker中所有executor需要用到连接时,从连接池中获取,用后归还。一般还是推荐这种方案。

下面说一下第二种方案的连接池,应该在什么时候初始化。

首先明确一点,在topology运行中,一个worker相当于jvm进程,相当于有N个worker,就会有N个连接池。初始化连接池的动作需要在worker端进行,一个worker中只有一个连接池的实例,适合用单例模式。

初始化思路:每个component接收数据库配置信息,在其prepare/open时,初始化连接池,这里需要保证在单个worker中只需要初始化一次就可以,即对初始化的代码加锁处理,保证只能有一个component初始化。

在storm源码包中,提供了storm-jdbc的实现,其中用了JDBC 连接池组件,具体实现思路就是上面讨论的第二种方案。以下为初始化时加锁的部分。

public class HikariCPConnectionProvider implements ConnectionProvider {

    private Map configMap;
    private transient HikariDataSource dataSource;

    public HikariCPConnectionProvider(Map hikariCPConfigMap) {
        this.configMap = hikariCPConfigMap;
    }

    @Override
    public synchronized void prepare() {
        if(dataSource == null) {
            Properties properties = new Properties();
            properties.putAll(configMap);
            HikariConfig config = new HikariConfig(properties);
            this.dataSource = new HikariDataSource(config);
            this.dataSource.setAutoCommit(false);
        }
    }

    @Override
    public Connection getConnection() {
        try {
            return this.dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void cleanup() {
        if(dataSource != null) {
            dataSource.shutdown();
        }
    }
}

看到,初始化prepare被上锁了,以保证只初始化一次。其实这里可以再优化一下:不要对方法加锁,而是对具体初始化连接的代码加锁,减少锁影响的范围。

到此,关于“component的生命周期怎么理解”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!


新闻标题:component的生命周期怎么理解
URL分享:http://cxhlcq.com/article/geceep.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部