精华内容
下载资源
问答
  • 2.国内IT名人大多优秀的学历背景,国外IT名人很多像盖茨、乔布斯、埃里森、扎克伯格没拿到学士学位的。 3.以上成功的IT企业家除了马云都是技术出身。 ========================================================...
    由于篇幅有限,只列举受公共认知度较高的创始人(百度百科对应人物词条被顶超过1000次)

    国内三强:
    李彦宏(百度创始人):本科就读于北京大学,硕士就读于布法罗纽约州立大学。曾任Infoseek工程师。
    马云(阿里巴巴创始人):本科就读于杭州师范学院。
    马化腾(腾讯创始人):本科就读于深圳大学。
    
    
    大三门户网站:
    王志东(新浪创始人):本科就读于北京大学,点击科技创始人。
    丁磊(网易创始人):本科就读于电子科技大学,曾在Sybase任工程师。
    张朝阳(搜狐创始人):本科就读于清华大学,硕士博士均就读于麻省理工学院,并在MIT从事博士后研究。
    
    
    创新科技公司代表:
    王小川(搜狗创始人):本科硕士均就读于清华大学,因IOI金牌保送到清华,现任搜狗CEO,原搜狐CTO。
    周鸿祎(360创始人):本科硕士均就读于西安交通大学,曾任雅虎中国区总裁。
    李开复(创新工场创始人):本科就读于哥伦比亚大学,博士就读于卡内基梅隆大学,曾在苹果,微软,谷歌任副总裁,创立MSRA并担任第一任院长
    
    
    老一辈代表:
    任正非(华为创始人):本科就读于重庆大学。
    柳传志(联想创始人):本科就读于西安电子科技大学。
    求伯君(金山创始人):本科就读于国防科技大学,中国编程第一人,独立发开WPS1.0。
    雷军(小米创始人):本科就读于武汉大学,曾任金山,卓越网,UCWEB,多玩董事长。
    
    
    电商代表:
    刘强东(京东商城创始人):本科就读于中国人民大学。
    
    李国庆(当当网创始人):本科就读于北京大学。
    
    陈欧(聚美优品创始人):本科就读于南洋理工大学 ,硕士就读于斯坦福大学,大学期间创办风靡世界的游戏平台Garena。
    
    
    交友网站代表:
    慕岩(百合网创始人):本科就读于清华大学,博士就读于马萨诸塞大学,曾就职于微软亚洲研究院和WebEx。
    陈一舟(人人网创始人):本科就读于武汉大学,硕士就读于麻省理工学院和斯坦福大学,ChinaRen创始人。
    
    
    网游代表:
    陈天桥(盛大网络创始人):本科就读于复旦大学。
    史玉柱(巨人网络创始人):本科就读于浙江大学,硕士就读于深圳大学。
    
    
    客观总结:
    1.国内成功的IT企业家绝大多数都出自国内外名校。
    2.国内IT名人大多有优秀的学历背景,国外IT名人很多像盖茨、乔布斯、埃里森、扎克伯格没拿到学士学位的。
    3.以上成功的IT企业家除了马云都是技术出身。
    
    

    ==================================================================================================

      作者:nash_  欢迎转载,与人分享是进步的源泉!

      转载请保留原文地址http://blog.csdn.net/nash_/article/details/8647839

    ===================================================================================================


    展开全文
  • 做事的常识,成功的公式

    千次阅读 2016-08-15 07:06:22
    开始+坚持+重复=成功,这就是做事的常识,但如何养成相应的习惯呢

    The best preparation for tomorrow is doing your best today.

    这里写图片描述
    我曾经在订阅号“程序视界”里推荐过一本书——《接受不完美的勇气》,作者是小仓广,当时我说把他的《交办的技术》和《做事的常识》加入了待购书单。现在,我买了《做事的常识》,一路保持兴奋把它读完了,特意来写这篇文章,把它推荐给大家,这本书,实在是太赞了,满满的干货和方法,对每一个想好好做事改变自己的人都有实践层面的指导意义。

    半途而废已成常态

    你想要每周读一本书,可往往:

    1. 今天下了决心,明天有别的事情,就把读书的事儿放下一边
    2. 这周读了一本,下周因为工作加班或者晚上和朋友聚会较多,只读了几页,于是计划每完成
    3. 这周没读完一本,下周又没读完,就对自己失去了信心,要么觉得这是不可能完成的任务,要么觉得自己不具备完成的毅力

    你想形成日事清的习惯,可往往:

    1. 早上领导叫你开会,一开两个小时,你的工作任务没时间完成
    2. 下午临近下班,同事突然找你讨论一个任务,说来说去一个小时过去了
    3. 你打算每天早上提前十分钟到公司,列出今天要完成的三件事,可周一因为堵车、周二因为下雨、周三因为送孩子上幼儿园、周四早上没什么事儿却睡过了头,结果一周四天都没能提前到公司
    4. 你准备每天下班前十分钟整理工作日志,列出今天完成的事情和未完成需求明天继续做的事情,可周一临近下班领导找你开会(同事让你帮忙看问题),开完会(看完问题)过了下班时间,你关了电脑就走了,周二类似……

    你想每天下班都和另一半聊至少20分钟,帮他(她)释放一天的压力和情绪,可往往:

    1. 你今天加班,回到家情绪不佳,不想聊了
    2. 你在单位遇到了不愉快的事儿,不愿意再听她唠叨
    3. 你晚上要和朋友聚会,回到家十点半了,没时间聊了
    4. 你心里一直琢磨着某个Bug,听她说话时心不在焉前言不搭后语,结果本来好好的减压谈话发展成了吵架,接下来几天你都不愿意跟她聊了

    我们每个人都会遇到类似的情况,想做一件事、想养成一个习惯、想实现一个目标,可往往半途而废,常常为此感到沮丧。

    把事情做出成绩的常识

    小仓广在《做事的常识》中写道:

    ……做事能够“坚持到底”的能力,不是与生俱来的,也不是只要对自己说“加油,要坚持下去”,就能做到。想拥有这种能力,必须经过“开始”、“坚持”、“重复”三个阶段的训练才能成功

    经过我的观察和亲身体验,我发现大部分容易半途而废的人,都是因为在这个三个阶段中,遇到以下的状况:

    第一阶段:开始
      很多人在做一件事之前,常把事情想得很困难、很复杂,害怕自己没准备好,常说“等我……就开始……”,很多事情都说说而已,根本无法开始。

    第二阶段:坚持
      成功最大的挑战,就在于克服路上的重重难关,还要小心不被负面思考打倒,但这恰恰就是多数人无法到达终点的最大阻碍。

    第三阶段:重复
      一般人好不容易把一件事情坚持做到最后,结果却不如预期,常会心生倦怠,不想再试一次。而且会用“毕竟我试过了”来安慰自己。毕竟放弃简单多了,但你也可能会因此错失大好机会。其实,你可能只是方法错误,不代表这件事是错的,或一定会失败。因此,我认为想要把事情做好的关键,就在于能接受失败,并且做到:反复练习,不怕重来。

    通过将做事分成开始、坚持、重复这三个阶段,小仓广认为半途而废的原因就是:

    1. 把事情想得太复杂,不敢开始
    2. 遇到干扰就分心,不能坚持
    3. 试过一次就放弃,不想再重复

    所以,《做事的常识》这本书就分为三部分,上篇讲怎样“养成立刻开始的好习惯”,中篇讲怎样“养成坚持到底的好习惯”,下篇讲如何“养成不怕重复的好习惯”。有了这三个习惯,就能达到借助习惯的力量,做到事情一来,马上就知道怎么做。

    养成立刻开始的好习惯

    “拆解问题”这部分,关于开始的技巧,有一张图:

    这张图和图前的解说非常形象、到位的描述了不能立刻开始的缘故和解决办法。上篇,“养成立刻开始的好习惯”,进一步细化了这张图,提供了许多有用的方法、技巧帮助我们建立立刻开始的习惯。比如:

    • 目标拆分,形成工作分解清单。做法其实很简单:
      • 首先,把目标写出来。
      • 接下来,在目标下面写上完成这个目标需要做的事。
      • 如果事情还可以细分,就再多写一层,直到分到最小单位为止。
      • 一旦复杂的任务细分成容易进行的小差事,你立刻就能知道自己现在该做什么,也立刻就可以开始做一个细分任务。
    • 找到自己的打气方式。工作上偶尔会遇到难度高又复杂的工作,这时候,就需要找出能激励自己工作情绪的小技巧。比如:
      • 听能唤起你热血的歌曲,如《洛奇》的主题曲,如汪正正的《超越梦想》,如许巍的《蓝莲花》
      • 读一句名人名言……
      • 看一段励志的文字
    • 练习负面思考,赶走负面思考。很多事情其实换个角度,感受就大为不同,当你能用积极心态来面对时,压力就没那么大,开始就没那么难。比如:
      • 原来的想法是“做这件事让我觉得很痛苦、很累”,可以转换为“做这件事在某些方面让我觉得快乐、值得、很有成就感”。
      • 原来的想法是“这份工作还有时间,晚一点再做吧”,可以转换为“我很期待这份工作的结果,迫不及待想要尽快开始”。
      • 原来的想法是“这份工作主管要求至少要做到……的程度才算完成”,可以转换为“这份工作是我自己选择的公司因为相信我,分配给我的工作。也就是说,这是我自己争取来的”。
    • 想象美好的结果,就能充满干劲。专心想象目标达成后的快乐、成就感,在脑子里形成一幅清晰的画面,确认自己看到了成功的画面,会让你更有动力,能帮你消除疲劳和不必要的忧虑,让你以最快的速度积极投入工作。
    • 及时反馈。小目标完成了,可以给自己一点小奖励(比如给自己买个小东西),没完成,给自己一点小惩罚(比如剥夺自己做自己想做的事情,如看球赛)。不断的正向反馈,会让你持续前进。而害怕不能做自己喜欢的事情的感觉也能让你尽力完成当下的小任务。

    这篇内容还有很多,都是非常实用的,可以细读。开始之后,就是坚持了,行百里者半九十。做事没有坚持,虎头蛇尾没什么卵用。

    养成坚持到底的好习惯

    关于坚持的图:

    这张图对比了抵制不了诱惑和坚持做事带来的差别,很形象。也许你看了这张图已经鸡血满满了。但《做事的常识》还用了很大的篇幅来介绍如何养成坚持到底的好习惯。

    • 积沙成塔的方法。完成梦想,就是要累积微不足道的小事。你每天写1页书,800字左右,一年就可以写一本书。钱钟书先生当时写围城,就是这样的习惯,每天500字。
    • 把重要但不紧急的事情放在黄金工作时间做。史蒂芬·柯维的《高效能人士的七个习惯》里提出了一个四象限法来进行时间管理,把事情分成不重要不紧急、紧急不重要、重要紧急、重要不紧急四种。小仓广的概念与史蒂芬·柯维类似,不过他还提出了黄金工作时间的概念,结合四象限法,你可以更好的工作。
      • 每个人都有精神状态好、思路清晰、效率高的一段时间,一般人是早上八点到中午十二点这段时间。他成这段时间为黄金工作时间。黄金工作时间内专心工作一小时相当于其它时间段三小时。
      • 把重要但不紧急的事情放在黄金工作时间来做。这样它们就不会演变成紧急重要的事情,你就不会陷入所有事情都是重要紧急的事情这种状态里,就不会整天忙得屁股冒烟还没什么收获。
      • 把杂事,诸如回复电子邮件、找资料、填写发票等,放在效率低下的时间段做,如下午两三点昏昏欲睡的时候。
    • 不要停下来,每天都要有进度。这是非常重要的,不积跬步无以至千里。合理划分任务,给每个人任务设定截止日期,工作不拖延,就比较容易做到这一点。
    • 把困难的事情做出乐趣。把棘手的、困难的工作拆分成不同阶段,在每个阶段找到让自己爱心的部分。比如要完成一百页的讲义,可以这样:
      • 告诉自己:我喜欢制作讲义
      • 看到特别满意的那几页,说出最满意的地方
      • 制作讲义的封面,并想象讲义完成的样子
      • 只要相处好创意,就大方赞美自己“我超强的”、“太厉害了”,肯定自己的表现
      • 一直想不出好点子时,用鼓舞人心的名言自我激励,像是“努力,就有收获”、“每个困难,都是成长的契机”等
      • 把写作过程想象成制作模型或拼拼图,用轻松的心情工作
    • 进度落后,先暂时跳过。还记得我们参加数学考试的过程吗?如果你遇到了一个不会解的难题,跳过去是最好的方法,否则你一直卡在那里,后面的题就没时间做了。工作中也是一样,因为你把复杂的事情已经细分了,这一个小任务卡住了,进度落后了,可以跳过去先做其他的,这样你就不会被沮丧打倒,也不太会耽误进度。
    • 公布你的计划和目标。有时你需要把自己置身在聚光灯下,让同事、朋友、家人监督你,你才能时刻保持警醒,努力坚持完成目标。

    有时即便你坚持了,也还是可能会失败。没错,事情并不是你努力了,你想成功,你就成了。所以,要接受无常,跌倒后重新爬起来。

    养成不怕重复的好习惯

    还是先上一幅图:

    小仓广在《做事的常识》里的配图,都是简单的线框加文字,但很形象,很赞。以后的我的书里也要插入能达到类似效果的图。

    这张图通过对比显示了重复的力量。但是重复的含义,并不是简单的重复错误,而是吃一堑长一智,从以前失败的经验里汲取教训,再次开始时要想着如何改善、改进做法,最终达到螺旋上升的效果,这样才能通向成功。

    在“养成不怕重复的好习惯”这一篇中,依然有很多方法、技巧、理念,帮助我们从失败中走出来,通过不管改进的重新开始,最终获得成功。

    • 失败几次无所谓,不放弃就不算输

    比起从不失败,那些跌倒后重新爬起来的人更值得尊敬。其实,成功的人和一般人最不一样的地方,就是他们永不放弃。

    弗弗西斯因为得罪了众神之王宙斯,而被判罚每天从山底推一块圆石头到山顶,当推到山顶时,石头从另一端滚下来,弗弗西斯再从山底向山顶推去,周而复始,永不停息。

    很多人可能会在失败时选择放弃,因为他们觉得自己已经试过了,再做的话也只会像弗弗西斯那样毫无意义。但实际上,正是因为弗弗西斯没有放弃,他的行为才拥有了超越惩罚和众神的意义。有时只有你不断重复、持续付出超越一般人的努力,才可能在最后一刻得到神的启示,逆转战局。这也是稻盛和夫在《干法》中倡导的理念。

    • 不因相同理由失败第二次,就算进步

    哀公问:“弟子孰为好学?”

    孔子对曰:“有颜回者好学,不迁怒,不贰过。不幸短命死矣!今也则亡,未闻好学者也。”

    颜回好学习,不把怒气发到别人头上,同样的错误不会犯第二次,是圣人。我们可能做不到那样,但当失败时,如能做到不乱归因给他人,客观的分析原因,从失败中学习经验,就可以有所进步,不会在同样的地方跌倒多次。

    所以,每一次失败后的重复,一定是带着改变重新开始的。

    • 断、舍、离

    之前推荐过《精要主义》,那本书的主旨就是“做得更少,但更好”。小仓广也持类似的理念,人的时间是有限的,不可能什么事儿不加选择的都能做过来,一定要断、舍、离。

    比如小仓广列出的工作上的“断、舍、离”(他是管理者):

    • 黄金工作时间不安排会议
    • 不参加非必要的会议
    • 不和员工一起拜访客户
    • 尊重中间主管的判断,不花太多时间细修部属的资料

    生活上的“断、舍、离”:

    • 不看电视
    • 不看杂志或体育新闻
    • 洗澡速战速决,不浪费时间
    • 参加应酬中途就离开,不留到最后
    • 不空等朋友,如果对方迟到,自己先离开再和对方联络
    • ……

    所以,你可以尝试列出自己的“断、舍、离”清单。

    • 不完美,真好

    人生原本就不完美,所以才要更懂得爱惜自己,不要勉强或伤害自己。要接纳自己的不完美,犯了错,不必不断责备自己,不要把错误看得太重(完全不在乎也不成)而陷入痛苦的深渊,这样对实现目标并没有帮助。要拥抱自己的不完美,才能再接再厉,勇敢爬起来。

    人生最美之处,就在于人生的不完美。

    • 别犹豫,做就对了

    不是不能做,只是不去做。

    小仓广引用日本宗教家西田天香的话来提醒那种无法改变现状、每天做事拖拖拉拉、为了工作疲于奔命的人。

    老天爷只会帮助懂得帮助自己,一步一个脚印,努力向目标迈进的人。而那些不想靠自己流汗打拼,只想要一步登天的人,即使是上帝也爱莫能助。这也是稻盛和夫所说的“神的启示”。

    开始+坚持+重复=成功


    参考阅读:

    展开全文
  • Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、...

    分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 

    Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。

    事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。

    Spring提供了如下所示的事务管理器。

    事务管理器实现类目标对象
    DataSourceTransactionManager注入DataSource
    HibernateTransactionManager注入SessionFactory
    JdoTransactionManager管理JDO事务
    JtaTransactionManager使用JTA管理事务
    PersistenceBrokerTransactionManager管理Apache的OJB事务

    这些事务的父接口都是PlatformTransactionManager。Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用JTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。

    编程式事务管理如下所示。

    <?xml version="1.0" encoding="UTF-8"?>
     <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:p="http://www.springframework.org/schema/p"
        xmlns:p="http://www.springframework.org/schema/context"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
         <context:component-scan base-package="com.jackfrued"/>
    
         <bean id="propertyConfig"
             class="org.springframework.beans.factory.config.
      PropertyPlaceholderConfigurer">
             <property name="location">
                 <value>jdbc.properties</value>
             </property>
         </bean>
    
         <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
             <property name="driverClassName">
                 <value>${db.driver}</value>
             </property>
             <property name="url">
                 <value>${db.url}</value>
             </property>
             <property name="username">
                 <value>${db.username}</value>
             </property>
             <property name="password">
                 <value>${db.password}</value>
             </property>
         </bean>
    
         <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
             <property name="dataSource">
                 <ref bean="dataSource" />
             </property>
         </bean>
    
         <!-- JDBC事务管理器 -->
         <bean id="transactionManager"
             class="org.springframework.jdbc.datasource.
           DataSourceTransactionManager" scope="singleton">
             <property name="dataSource">
                 <ref bean="dataSource" />
             </property>
         </bean>
    
         <!-- 声明事务模板 -->
         <bean id="transactionTemplate"
             class="org.springframework.transaction.support.
       TransactionTemplate">
             <property name="transactionManager">
                 <ref bean="transactionManager" />
             </property>
         </bean>
    
    </beans>
    package chimomo.learning.java.code.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import chimomo.learning.java.code.spring.EmpDao;
    import chimomo.learning.java.code.spring.Emp;
    
    @Repository
    public class EmpDaoImpl implements EmpDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Override
        public boolean save(Emp emp) {
            String sql = "insert into emp values (?,?,?)";
            return jdbcTemplate.update(sql, emp.getId(), emp.getName(), emp.getBirthday()) == 1;
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.support.TransactionCallbackWithoutResult;
    import org.springframework.transaction.support.TransactionTemplate;
    
    import chimomo.learning.java.code.spring.EmpService;
    import chimomo.learning.java.code.spring.EmpDao;
    import chimomo.learning.java.code.spring.Emp;
    
    @Service
    public class EmpServiceImpl implements EmpService {
        @Autowired
        private TransactionTemplate txTemplate;
        @Autowired
        private EmpDao empDao;
    
        @Override
        public void addEmp(final Emp emp) {
            txTemplate.execute(new TransactionCallbackWithoutResult() {
    
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
                    empDao.save(emp);
                }
            });
        }
    
    }

    声明式事务如下所示,以Spring整合Hibernate 3为例,包括完整的DAO和业务逻辑代码。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop" 
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.2.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
    
        <!-- 配置由Spring IoC容器托管的对象对应的被注解的类所在的包 -->
        <context:component-scan base-package="com.jackfrued" />
    
        <!-- 配置通过自动生成代理实现AOP功能 -->
        <aop:aspectj-autoproxy />
    
        <!-- 配置数据库连接池 (DBCP) -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <!-- 配置驱动程序类 -->
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <!-- 配置连接数据库的URL -->
            <property name="url" value="jdbc:mysql://localhost:3306/myweb" />
            <!-- 配置访问数据库的用户名 -->
            <property name="username" value="root" />
            <!-- 配置访问数据库的口令 -->
            <property name="password" value="123456" />
            <!-- 配置最大连接数 -->
            <property name="maxActive" value="150" />
            <!-- 配置最小空闲连接数 -->
            <property name="minIdle" value="5" />
            <!-- 配置最大空闲连接数 -->
            <property name="maxIdle" value="20" />
            <!-- 配置初始连接数 -->
            <property name="initialSize" value="10" />
            <!-- 配置连接被泄露时是否生成日志 -->
            <property name="logAbandoned" value="true" />
            <!-- 配置是否删除超时连接 -->
            <property name="removeAbandoned" value="true" />
            <!-- 配置删除超时连接的超时门限值(以秒为单位) -->
            <property name="removeAbandonedTimeout" value="120" />
            <!-- 配置超时等待时间(以毫秒为单位) -->
            <property name="maxWait" value="5000" />
            <!-- 配置空闲连接回收器线程运行的时间间隔(以毫秒为单位) -->
            <property name="timeBetweenEvictionRunsMillis" value="300000" />
            <!-- 配置连接空闲多长时间后(以毫秒为单位)被断开连接 -->
            <property name="minEvictableIdleTimeMillis" value="60000" />
        </bean>
    
        <!-- 配置Spring提供的支持注解ORM映射的Hibernate会话工厂 -->
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <!-- 通过setter注入数据源属性 -->
            <property name="dataSource" ref="dataSource" />
            <!-- 配置实体类所在的包 -->
            <property name="packagesToScan" value="com.jackfrued.entity" />
            <!-- 配置Hibernate的相关属性 -->
            <property name="hibernateProperties">
                <!-- 在项目调试完成后要删除show_sql和format_sql属性否则对性能有显著影响 -->
                <value>
                    hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                </value>
            </property>
        </bean>
    
        <!-- 配置Spring提供的Hibernate事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <!-- 通过setter注入Hibernate会话工厂 -->
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
        <!-- 配置基于注解配置声明式事务 -->
        <tx:annotation-driven />
    
    </beans>
    package chimomo.learning.java.code.spring;
    
    import java.io.Serializable;
    import java.util.List;
    
    import chimomo.learning.java.code.spring.QueryBean;
    import chimomo.learning.java.code.spring.QueryResult;
    
    /**
     * 数据访问对象接口(以对象为单位封装CRUD操作)
     *
     * @param <E> 实体类型
     * @param <K> 实体标识字段的类型
     */
    public interface BaseDao <E, K extends Serializable> {
    
        /**
         * 新增
         * @param entity 业务实体对象
         * @return 增加成功返回实体对象的标识
         */
        public K save(E entity);
    
        /**
         * 删除
         * @param entity 业务实体对象
         */
        public void delete(E entity);
    
        /**
         * 根据ID删除
         * @param id 业务实体对象的标识
         * @return 删除成功返回true否则返回false
         */
        public boolean deleteById(K id);
    
        /**
         * 修改
         * @param entity 业务实体对象
         * @return 修改成功返回true否则返回false
         */
        public void update(E entity);
    
        /**
         * 根据ID查找业务实体对象
         * @param id 业务实体对象的标识
         * @return 业务实体对象对象或null
         */
        public E findById(K id);
    
        /**
         * 根据ID查找业务实体对象
         * @param id 业务实体对象的标识
         * @param lazy 是否使用延迟加载
         * @return 业务实体对象对象
         */
        public E findById(K id, boolean lazy);
    
        /**
         * 查找所有业务实体对象
         * @return 装所有业务实体对象的列表容器
         */
        public List<E> findAll();
    
        /**
         * 分页查找业务实体对象
         * @param page 页码
         * @param size 页面大小
         * @return 查询结果对象
         */
        public QueryResult<E> findByPage(int page, int size);
    
        /**
         * 分页查找业务实体对象
         * @param queryBean 查询条件对象
         * @param page 页码
         * @param size 页面大小
         * @return 查询结果对象
         */
        public QueryResult<E> findByPage(QueryBean queryBean, int page, int size);
    
    }
    package chimomo.learning.java.code.spring;
    
    import java.io.Serializable;
    import java.util.List;
    
    import chimomo.learning.java.code.spring.QueryBean;
    import chimomo.learning.java.code.spring.QueryResult;
    
    /**
     * BaseDao的缺省适配器
     *
     * @param <E> 实体类型
     * @param <K> 实体标识字段的类型
     */
    public abstract class BaseDaoAdapter<E, K extends Serializable> implements
            BaseDao<E, K> {
    
        @Override
        public K save(E entity) {
            return null;
        }
    
        @Override
        public void delete(E entity) {
        }
    
        @Override
        public boolean deleteById(K id) {
            E entity = findById(id);
            if(entity != null) {
                delete(entity);
                return true;
            }
            return false;
        }
    
        @Override
        public void update(E entity) {
        }
    
        @Override
        public E findById(K id) {
            return null;
        }
    
        @Override
        public E findById(K id, boolean lazy) {
            return null;
        }
    
        @Override
        public List<E> findAll() {
            return null;
        }
    
        @Override
        public QueryResult<E> findByPage(int page, int size) {
            return null;
        }
    
        @Override
        public QueryResult<E> findByPage(QueryBean queryBean, int page, int size) {
            return null;
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import chimomo.learning.java.code.spring.HQLQueryBean;
    import chimomo.learning.java.code.spring.QueryBean;
    import chimomo.learning.java.code.spring.QueryResult;
    
    /**
     * 基于Hibernate的BaseDao实现类
     *
     * @param <E> 实体类型
     * @param <K> 主键类型
     */
    @SuppressWarnings(value = {"unchecked"})
    public abstract class BaseDaoHibernateImpl<E, K extends Serializable> extends BaseDaoAdapter<E, K> {
        @Autowired
        protected SessionFactory sessionFactory;
    
        private Class<?> entityClass;       // 业务实体的类对象
        private String entityName;          // 业务实体的名字
    
        public BaseDaoHibernateImpl() {
            ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
            entityClass = (Class<?>) pt.getActualTypeArguments()[0];
            entityName = entityClass.getSimpleName();
        }
    
        @Override
        public K save(E entity) {
            return (K) sessionFactory.getCurrentSession().save(entity);
        }
    
        @Override
        public void delete(E entity) {
            sessionFactory.getCurrentSession().delete(entity);
        }
    
        @Override
        public void update(E entity) {
            sessionFactory.getCurrentSession().update(entity);
        }
    
        @Override
        public E findById(K id) {
            return findById(id, false);
        }
    
        @Override
        public E findById(K id, boolean lazy) {
            Session session = sessionFactory.getCurrentSession();
            return (E) (lazy? session.load(entityClass, id) : session.get(entityClass, id));
        }
    
        @Override
        public List<E> findAll() {
            return sessionFactory.getCurrentSession().createCriteria(entityClass).list();
        }
    
        @Override
        public QueryResult<E> findByPage(int page, int size) {
            return new QueryResult<E>(
                findByHQLAndPage("from " + entityName , page, size),
                getCountByHQL("select count(*) from " + entityName)
            );
        }
    
        @Override
        public QueryResult<E> findByPage(QueryBean queryBean, int page, int size) {
            if(queryBean instanceof HQLQueryBean) {
                HQLQueryBean hqlQueryBean = (HQLQueryBean) queryBean;
                return new QueryResult<E>(
                    findByHQLAndPage(hqlQueryBean.getQueryString(), page, size, hqlQueryBean.getParameters()),
                    getCountByHQL(hqlQueryBean.getCountString(), hqlQueryBean.getParameters())
                );
            }
            return null;
        }
    
        /**
         * 根据HQL和可变参数列表进行查询
         * @param hql 基于HQL的查询语句
         * @param params 可变参数列表
         * @return 持有查询结果的列表容器或空列表容器
         */
        protected List<E> findByHQL(String hql, Object... params) {
            return this.findByHQL(hql, getParamList(params));
        }
    
        /**
         * 根据HQL和参数列表进行查询
         * @param hql 基于HQL的查询语句
         * @param params 查询参数列表
         * @return 持有查询结果的列表容器或空列表容器
         */
        protected List<E> findByHQL(String hql, List<Object> params) {
            List<E> list = createQuery(hql, params).list();
            return list != null && list.size() > 0 ? list : Collections.EMPTY_LIST;
        }
    
        /**
         * 根据HQL和参数列表进行分页查询
         * @param hql 基于HQL的查询语句
         * @page 页码
         * @size 页面大小
         * @param params 可变参数列表
         * @return 持有查询结果的列表容器或空列表容器
         */
        protected List<E> findByHQLAndPage(String hql, int page, int size, Object... params) {
            return this.findByHQLAndPage(hql, page, size, getParamList(params));
        }
    
        /**
         * 根据HQL和参数列表进行分页查询
         * @param hql 基于HQL的查询语句
         * @page 页码
         * @size 页面大小
         * @param params 查询参数列表
         * @return 持有查询结果的列表容器或空列表容器
         */
        protected List<E> findByHQLAndPage(String hql, int page, int size, List<Object> params) {
            List<E> list = createQuery(hql, params)
                    .setFirstResult((page - 1) * size)
                    .setMaxResults(size)
                    .list();
            return list != null && list.size() > 0 ? list : Collections.EMPTY_LIST;
        }
    
        /**
         * 查询满足条件的记录数
         * @param hql 基于HQL的查询语句
         * @param params 可变参数列表
         * @return 满足查询条件的总记录数
         */
        protected long getCountByHQL(String hql, Object... params) {
            return this.getCountByHQL(hql, getParamList(params));
        }
    
        /**
         * 查询满足条件的记录数
         * @param hql 基于HQL的查询语句
         * @param params 参数列表容器
         * @return 满足查询条件的总记录数
         */
        protected long getCountByHQL(String hql, List<Object> params) {
            return (Long) createQuery(hql, params).uniqueResult();
        }
    
        // 创建Hibernate查询对象(Query)
        private Query createQuery(String hql, List<Object> params) {
            Query query = sessionFactory.getCurrentSession().createQuery(hql);
            for(int i = 0; i < params.size(); i++) {
                query.setParameter(i, params.get(i));
            }
            return query;
        }
    
        // 将可变参数列表组装成列表容器
        private List<Object> getParamList(Object... params) {
            List<Object> paramList = new ArrayList<>();
            if(params != null) {
                for(int i = 0; i < params.length; i++) {
                    paramList.add(params[i]);
                }
            }
            return paramList.size() == 0? Collections.EMPTY_LIST : paramList;
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    import java.util.List;
    
    /**
     * 查询条件的接口
     *
     */
    public interface QueryBean {
    
        /**
         * 添加排序字段
         * @param fieldName 用于排序的字段
         * @param asc 升序还是降序
         * @return 查询条件对象自身(方便级联编程)
         */
        public QueryBean addOrder(String fieldName, boolean asc);
    
        /**
         * 添加排序字段
         * @param available 是否添加此排序字段
         * @param fieldName 用于排序的字段
         * @param asc 升序还是降序
         * @return 查询条件对象自身(方便级联编程)
         */
        public QueryBean addOrder(boolean available, String fieldName, boolean asc);
    
        /**
         * 添加查询条件
         * @param condition 条件
         * @param params 替换掉条件中参数占位符的参数
         * @return 查询条件对象自身(方便级联编程)
         */
        public QueryBean addCondition(String condition, Object... params);
    
        /**
         * 添加查询条件
         * @param available 是否需要添加此条件
         * @param condition 条件
         * @param params 替换掉条件中参数占位符的参数
         * @return 查询条件对象自身(方便级联编程)
         */
        public QueryBean addCondition(boolean available, String condition, Object... params);
    
        /**
         * 获得查询语句
         * @return 查询语句
         */
        public String getQueryString();
    
        /**
         * 获取查询记录数的查询语句
         * @return 查询记录数的查询语句
         */
        public String getCountString();
    
        /**
         * 获得查询参数
         * @return 查询参数的列表容器
         */
        public List<Object> getParameters();
    }
    package chimomo.learning.java.code.spring;
    
    import java.util.List;
    
    /**
     * 查询结果
     *
     * @param <T> 泛型参数
     */
    public class QueryResult<T> {
        private List<T> result;     // 持有查询结果的列表容器
        private long totalRecords;  // 查询到的总记录数
    
        /**
         * 构造器
         */
        public QueryResult() {
        }
    
        /**
         * 构造器
         * @param result 持有查询结果的列表容器
         * @param totalRecords 查询到的总记录数
         */
        public QueryResult(List<T> result, long totalRecords) {
            this.result = result;
            this.totalRecords = totalRecords;
        }
    
        public List<T> getResult() {
            return result;
        }
    
        public void setResult(List<T> result) {
            this.result = result;
        }
    
        public long getTotalRecords() {
            return totalRecords;
        }
    
        public void setTotalRecords(long totalRecords) {
            this.totalRecords = totalRecords;
        }
    }
    package chimomo.learning.java.code.spring;
    
    import chimomo.learning.java.code.spring.QueryResult;
    import chimomo.learning.java.code.spring.Dept;
    
    /**
     * 部门数据访问对象接口
     *
     */
    public interface DeptDao extends BaseDao<Dept, Integer> {
    
        /**
         * 分页查询顶级部门
         * @param page 页码
         * @param size 页码大小
         * @return 查询结果对象
         */
        public QueryResult<Dept> findTopDeptByPage(int page, int size);
    
    }
    package chimomo.learning.java.code.spring;
    
    import java.util.List;
    
    import org.springframework.stereotype.Repository;
    
    import chimomo.learning.java.code.spring.QueryResult;
    import chimomo.learning.java.code.spring.BaseDaoHibernateImpl;
    import chimomo.learning.java.code.spring.DeptDao;
    import chimomo.learning.java.code.spring.Dept;
    
    @Repository
    public class DeptDaoImpl extends BaseDaoHibernateImpl<Dept, Integer> implements DeptDao {
        private static final String HQL_FIND_TOP_DEPT = " from Dept as d where d.superiorDept is null ";
    
        @Override
        public QueryResult<Dept> findTopDeptByPage(int page, int size) {
            List<Dept> list = findByHQLAndPage(HQL_FIND_TOP_DEPT, page, size);
            long totalRecords = getCountByHQL(" select count(*) " + HQL_FIND_TOP_DEPT);
            return new QueryResult<>(list, totalRecords);
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    import java.util.List;
    
    /**
     * 分页器
     *
     * @param <T> 分页数据对象的类型
     */
    public class PageBean<T> {
        private static final int DEFAUL_INIT_PAGE = 1;
        private static final int DEFAULT_PAGE_SIZE = 10;
        private static final int DEFAULT_PAGE_COUNT = 5;
    
        private List<T> data;           // 分页数据
        private PageRange pageRange;    // 页码范围
        private int totalPage;          // 总页数
        private int size;               // 页面大小
        private int currentPage;        // 当前页码
        private int pageCount;          // 页码数量
    
        /**
         * 构造器
         * @param currentPage 当前页码
         * @param size 页码大小
         * @param pageCount 页码数量
         */
        public PageBean(int currentPage, int size, int pageCount) {
            this.currentPage = currentPage > 0 ? currentPage : 1;
            this.size = size > 0 ? size : DEFAULT_PAGE_SIZE;
            this.pageCount = pageCount > 0 ? size : DEFAULT_PAGE_COUNT;
        }
    
        /**
         * 构造器
         * @param currentPage 当前页码
         * @param size 页码大小
         */
        public PageBean(int currentPage, int size) {
            this(currentPage, size, DEFAULT_PAGE_COUNT);
        }
    
        /**
         * 构造器
         * @param currentPage 当前页码
         */
        public PageBean(int currentPage) {
            this(currentPage, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT);
        }
    
        /**
         * 构造器
         */
        public PageBean() {
            this(DEFAUL_INIT_PAGE, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_COUNT);
        }
    
        public List<T> getData() {
            return data;
        }
    
        public int getStartPage() {
            return pageRange != null ? pageRange.getStartPage() : 1;
        }
    
        public int getEndPage() {
            return pageRange != null ? pageRange.getEndPage() : 1;
        }
    
        public long getTotalPage() {
            return totalPage;
        }
    
        public int getSize() {
            return size;
        }
    
        public int getCurrentPage() {
            return currentPage;
        }
    
        /**
         * 将查询结果转换为分页数据
         * @param queryResult 查询结果对象
         */
        public void transferQueryResult(QueryResult<T> queryResult) {
            long totalRecords = queryResult.getTotalRecords();
    
            data = queryResult.getResult();
            totalPage = (int) ((totalRecords + size - 1) / size); 
            totalPage = totalPage >= 0 ? totalPage : Integer.MAX_VALUE;
            this.pageRange = new PageRange(pageCount, currentPage, totalPage);
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    /**
     * 页码范围
     *
     */
    public class PageRange {
        private int startPage;  // 起始页码
        private int endPage;    // 终止页码
    
        /**
         * 构造器
         * @param pageCount 总共显示几个页码
         * @param currentPage 当前页码
         * @param totalPage 总页数
         */
        public PageRange(int pageCount, int currentPage, int totalPage) {
            startPage = currentPage - (pageCount - 1) / 2;
            endPage = currentPage + pageCount / 2;
            if(startPage < 1) {
                startPage = 1;
                endPage = totalPage > pageCount ? pageCount : totalPage;
            }
            if (endPage > totalPage) {
                endPage = totalPage;
                startPage = (endPage - pageCount > 0) ? endPage - pageCount + 1 : 1;
            }
        }
    
        /**
         * 获得起始页页码
         * @return 起始页页码
         */
        public int getStartPage() {
            return startPage;
        }
    
        /**
         * 获得终止页页码
         * @return 终止页页码
         */
        public int getEndPage() {
            return endPage;
        }
    
    }
    package chimomo.learning.java.code.spring;
    
    import chimomo.learning.java.code.spring.PageBean;
    import chimomo.learning.java.code.spring.Dept;
    
    /**
     * 部门业务逻辑接口
     *
     */
    public interface DeptService {
    
        /**
         * 创建新的部门
         * @param department 部门对象
         * @return 创建成功返回true否则返回false
         */
        public boolean createNewDepartment(Dept department);
    
        /**
         * 删除指定部门
         * @param id 要删除的部门的编号
         * @return 删除成功返回true否则返回false
         */
        public boolean deleteDepartment(Integer id);
    
        /**
         * 分页获取顶级部门
         * @param page 页码
         * @param size 页码大小
         * @return 部门对象的分页器对象
         */
        public PageBean<Dept> getTopDeptByPage(int page, int size);
    
    }
    package chimomo.learning.java.code.spring;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import chimomo.learning.java.code.spring.DeptService;
    import chimomo.learning.java.code.spring.PageBean;
    import chimomo.learning.java.code.spring.QueryResult;
    import chimomo.learning.java.code.spring.DeptDao;
    import chimomo.learning.java.code.spring.Dept;
    
    @Service
    @Transactional  // 声明式事务的注解
    public class DeptServiceImpl implements DeptService {
        @Autowired
        private DeptDao deptDao;
    
        @Override
        public boolean createNewDepartment(Dept department) {
            return deptDao.save(department) != null;
        }
    
        @Override
        public boolean deleteDepartment(Integer id) {
            return deptDao.deleteById(id);
        }
    
        @Override
        public PageBean<Dept> getTopDeptByPage(int page, int size) {
            QueryResult<Dept> queryResult = deptDao.findTopDeptByPage(page, size);
            PageBean<Dept> pageBean = new PageBean<>(page, size);
            pageBean.transferQueryResult(queryResult);
            return pageBean;
        }
    
    }

     

    展开全文
  • RocketMQ——ack机制保证消费成功

    万次阅读 热门讨论 2018-06-26 10:38:12
    在实际使用RocketMQ的时候我们并不能保证每次发送的消息都刚好能被消费者一次性正常消费成功,可能会存在需要多次消费才能成功或者一直消费失败的情况,那作为发送者该做如何处理呢? RocketMQ提供了ack机制,以...

    ACK简介

    在实际使用RocketMQ的时候我们并不能保证每次发送的消息都刚好能被消费者一次性正常消费成功,可能会存在需要多次消费才能成功或者一直消费失败的情况,那作为发送者该做如何处理呢?

    RocketMQ提供了ack机制,以保证消息能够被正常消费。发送者为了保证消息肯定消费成功,只有使用方明确表示消费成功,RocketMQ才会认为消息消费成功。中途断电,抛出异常等都不会认为成功——即都会重新投递。

    DEMO

    当然,如果消费者不告知发送者我这边消费信息异常,那么发送者是不会知道的,所以消费者在设置监听的时候需要给个回调,具体代码如下:

    consumer.registerMessageListener(new MessageListenerConcurrently() {  
      
                 @Override  
                 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,  
                                                                 ConsumeConcurrentlyContext context) {  
                     for (MessageExt messageExt : msgs) {    
                        String messageBody = new String(messageExt.getBody());    
                        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(
                        		 new Date())+"消费响应:msgId : " + messageExt.getMsgId() + ",  msgBody : " + messageBody);//输出消息内容    
                     }    
                       
                     //返回消费状态  
                     //CONSUME_SUCCESS 消费成功  
                     //RECONSUME_LATER 消费失败,需要稍后重新消费  
                     return ConsumeConcurrentlyStatus.RECONSUME_LATER;  
                 }  
             }); 

     

     

    业务实现消费回调的时候,当且仅当此回调函数返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS,RocketMQ才会认为这批消息(默认是1条)是消费完成的。如果这时候消息消费失败,例如数据库异常,余额不足扣款失败等一切业务认为消息需要重试的场景,只要返回ConsumeConcurrentlyStatus.RECONSUME_LATER,RocketMQ就会认为这批消息消费失败了。

     

     

    为了保证消息是肯定被至少消费成功一次,RocketMQ会把这批消息重发回Broker(topic不是原topic而是这个消费租的RETRY topic),在延迟的某个时间点(默认是10秒,业务可设置)后,再次投递到这个ConsumerGroup。而如果一直这样重复消费都持续失败到一定次数(默认16次),就会投递到DLQ死信队列。应用可以监控死信队列来做人工干预。

     

    修改重试时间

    重试的时间默认如下,这个可以通过查看broker的日志,

    messageDelayLevel = 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

     

    当然,这个重复的时间间隔是可以在配置文件内设置的,由于我这边配置的双master模式,所以在128服务器的broker-a.properties和129的broker-b.properties中分别配置,如下图,设置好后务必将之前的数据清理,具体查看RocketMQ双Master环境部署

     

    messageDelayLevel = 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s 5s

    重试消息的处理

    一般情况下我们在实际生产中是不需要重试16次,这样既浪费时间又浪费性能,理论上当尝试重复次数达到我们想要的结果时如果还是消费失败,那么我们需要将对应的消息进行记录,并且结束重复尝试。

    package com.gwd.rocketmq;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
    import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
    import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
    import com.alibaba.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
    import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
    import com.alibaba.rocketmq.client.exception.MQClientException;
    import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
    import com.alibaba.rocketmq.common.message.MessageExt;
    import com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
    
    /** 
    * @FileName Consumer.java
    * @Description:
    * @author gu.weidong
    * @version V1.0
    * @createtime 2018年6月25日 上午9:49:39 
    * 修改历史:
    * 时间           作者          版本        描述
    *====================================================  
    *
    */
    public class Consumer {
    	public static void main(String[] args) throws MQClientException {  
            
            //声明并初始化一个consumer  
             //需要一个consumer group名字作为构造方法的参数,这里为consumer1  
             DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer1");  
      
             //同样也要设置NameServer地址  
             consumer.setNamesrvAddr("192.168.159.128:9876;192.168.159.129:9876");  
             //这里设置的是一个consumer的消费策略  
             //CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,即跳过历史消息  
             //CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍  
             //CONSUME_FROM_TIMESTAMP 从某个时间点开始消费,和setConsumeTimestamp()配合使用,默认是半个小时以前  
             consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);  
             //设置consumer所订阅的Topic和Tag,*代表全部的Tag  
             consumer.subscribe("TopicTest", "*");  
            //设置一个Listener,主要进行消息的逻辑处理  
             consumer.registerMessageListener(new MessageListenerConcurrently() {  
                 @Override  
                 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,  
                                                                 ConsumeConcurrentlyContext context) {  
                     for (MessageExt messageExt : msgs) {    
    	                 if(messageExt.getReconsumeTimes()==3) {
    	                	 //可以将对应的数据保存到数据库,以便人工干预
    	                	 System.out.println(messageExt.getMsgId()+","+messageExt.getBody());
    	                	 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    	                 }
                     }       
                     //返回消费状态  
                     //CONSUME_SUCCESS 消费成功  
                     //RECONSUME_LATER 消费失败,需要稍后重新消费  
                     return ConsumeConcurrentlyStatus.RECONSUME_LATER;  
                 }  
             });  
             //调用start()方法启动consumer  
             consumer.start();  
             System.out.println("Consumer Started.");  
         }  
    }
    

     

     

     

    所以任何异常都要捕获返回ConsumeConcurrentlyStatus.RECONSUME_LATER,rocketmq会放到重试队列,这个重试TOPIC的名字是%RETRY%+consumergroup的名字,如下图:

     

     

     

    注意点

     

    1.如果业务的回调没有处理好而抛出异常,会认为是消费失败当ConsumeConcurrentlyStatus.RECONSUME_LATER处理。

     

    2.当使用顺序消费的回调MessageListenerOrderly时,由于顺序消费是要前者消费成功才能继续消费,所以没有ConsumeConcurrentlyStatus.RECONSUME_LATER的这个状态,只有ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT来暂停队列的其余消费,直到原消息不断重试成功为止才能继续消费。

     

    测试案例

    (1)producer

    package com.gwd.rocketmq;
    
    import com.alibaba.rocketmq.client.exception.MQClientException;
    import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
    import com.alibaba.rocketmq.client.producer.SendResult;
    import com.alibaba.rocketmq.common.message.Message;
    
    /** 
    * @FileName Producer.java
    * @Description:
    * @author gu.weidong
    * @version V1.0
    * @createtime 2018年6月25日 上午9:48:37 
    * 修改历史:
    * 时间           作者          版本        描述
    *====================================================  
    *
    */
    public class Producer {
    	public static void main(String[] args) throws MQClientException, InterruptedException {  
            //声明并初始化一个producer  
            //需要一个producer group名字作为构造方法的参数,这里为producer1  
            DefaultMQProducer producer = new DefaultMQProducer("producer1");  
              
            //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔  
            //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里  
            producer.setNamesrvAddr("192.168.140.128:9876;192.168.140.129:9876");  
       //     producer.setVipChannelEnabled(false);//3.2。6的版本没有该设置,在更新或者最新的版本中务必将其设置为false,否则会有问题  
            //调用start()方法启动一个producer实例  
            producer.start();  
      
            //发送10条消息到Topic为TopicTest,tag为TagA,消息内容为“Hello RocketMQ”拼接上i的值  
            for (int i = 0; i < 5; i++) {  
                try {  
                    Message msg = new Message("TopicTest",// topic  
                            "TagA",// tag  
                            ("Hello RocketMQ " + i).getBytes("utf-8")// body  
                    );          
                    //调用producer的send()方法发送消息  
                    //这里调用的是同步的方式,所以会有返回结果  
                    SendResult sendResult = producer.send(msg);  
                    //打印返回结果,可以看到消息发送的状态以及一些相关信息  
                    System.out.println(sendResult);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    Thread.sleep(1000);  
                }  
            }  
      
            //发送完消息之后,调用shutdown()方法关闭producer  
            producer.shutdown();  
        }  
    }
    

    (2)Consumer

    package com.gwd.rocketmq;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
    import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
    import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
    import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
    import com.alibaba.rocketmq.client.exception.MQClientException;
    import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
    import com.alibaba.rocketmq.common.message.MessageExt;
    import com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
    
    /** 
    * @FileName Consumer.java
    * @Description:
    * @author gu.weidong
    * @version V1.0
    * @createtime 2018年6月25日 上午9:49:39 
    * 修改历史:
    * 时间           作者          版本        描述
    *====================================================  
    *
    */
    public class Consumer {
    	public static void main(String[] args) throws MQClientException {  
            
            //声明并初始化一个consumer  
             //需要一个consumer group名字作为构造方法的参数,这里为consumer1  
             DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer1");  
      
             //同样也要设置NameServer地址  
             consumer.setNamesrvAddr("192.168.140.128:9876;192.168.140.129:9876");  
             //这里设置的是一个consumer的消费策略  
             //CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,即跳过历史消息  
             //CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍  
             //CONSUME_FROM_TIMESTAMP 从某个时间点开始消费,和setConsumeTimestamp()配合使用,默认是半个小时以前  
             consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);  
      
             //设置consumer所订阅的Topic和Tag,*代表全部的Tag  
             consumer.subscribe("TopicTest", "*");  
      
             //设置一个Listener,主要进行消息的逻辑处理  
             consumer.registerMessageListener(new MessageListenerConcurrently() {  
                 @Override  
                 public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,  
                                                                 ConsumeConcurrentlyContext context) {  
                     for (MessageExt messageExt : msgs) {    
                        String messageBody = new String(messageExt.getBody());    
                         System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(
                        		 new Date())+"消费响应:msgId : " + messageExt.getMsgId() + ",  msgBody : " + messageBody);//输出消息内容    
                     }    
                     //返回消费状态  
                     //CONSUME_SUCCESS 消费成功  
                     //RECONSUME_LATER 消费失败,需要稍后重新消费  
                     return ConsumeConcurrentlyStatus.RECONSUME_LATER;  
                 }  
             });  
             //调用start()方法启动consumer  
             consumer.start();  
             System.out.println("Consumer Started.");  
         }  
    }
    

    (3)测试结果如下

    展开全文
  • delete from tableName where colName = 'colname' 即使不存在名字为 colname的这一条记录,sql也是执行成功。 那么,如何判断sql执行之后是否会返回我们希望的结果呢? Statement 接口提供三种 执行SQL 方法:...
  • 问了客服,说是这种错误码代表 appID没有支付权限,或者签名字串不对。 通了两天终于支付成功了。 给遇到同样问题的朋友一个总结就是,一定和你的后台商量好 都有哪些字段,一定要一模一样,key、value、以及每个...
  • http请求头有哪些字段

    千次阅读 2019-03-28 10:23:25
    Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。 User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。 UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE...
  • 要搞清楚这个问题首先要明白什么是架构,之前也很多人提到了架构不同,但架构是什么意思?它是一个比较抽象的概念,不太容易用几句话就解释清楚。我们要明白CPU是一个执行部件,它之所以能执行,也是因为人们在...
  • Redis集群都有哪些模式

    千次阅读 2018-10-08 15:42:54
    为了避免一致性哈希只影响相邻节点造成节点分配压力,ShardedJedis会对每个Redis节点根据名字(没有,Jedis会赋予缺省名字)会虚拟化出160个虚拟节点进行散列。根据权重weight,也可虚拟化出160倍数的虚拟节点。用虚拟...
  • NoSQL代表: Mongo DB(芒果数据库)

    千次阅读 2013-01-30 22:12:58
    NoSQL代表: Mongo DB(芒果数据库) 分类: Mongo DB2012-02-28 20:46 2768人阅读 评论(0) 收藏 举报    一、MongoDB简介  MongoDB是一个基于分布式文件存储的数据库,由C++语言编写,旨在为...
  • Nombas 最终把 Cmm 的名字改成了 ScriptEase,原因是后面的部分(mm)听起来过于消极,同时字母 C “令人害怕”。 现在 ScriptEase 已经成为了 Nombas 产品背后的主要驱动力。 2、Netscape发明了...
  • Android之父安迪·鲁宾:极客文化的代表 2011-08-15 09:17 来源:东方网-文汇报  RSS复制链接打印 核心提示:他就像当年的比尔·盖茨一样,踩在一条宽广的IT未来之路上,只不过当年那条路通向个人电脑,而今天...
  • 代表对过去的留恋

    千次阅读 2011-02-24 21:14:00
     代表有对艺术或创作方面的灵感,对从事这种行业的人来说是个好梦。  八  事业运的暗示。梦见这个数字,你需要从梦中的感觉去解释。如果在梦中心情好的话、事业运会上升,相反...。  九  代表变化。现有的...
  • 管斌全:《学习成功:中学生成就梦想的15堂必修课》笛案:自信国内外成功学的著作看过不少,但我只向人推荐管斌全的作品。以下内容节选自网络,个人渠道还是买书好,也算是对作者的支持。fygub0231@sina....
  • OSI七层模型的每一层都有哪些协议

    万次阅读 多人点赞 2012-11-27 20:13:07
    ATP(AppleTalk Transaction Protocol),NBP(名字绑定协议)   NetBEUI(NetBIOS Extended User Internet)   3、网络层协议   网络层协议提供所谓的链路服务,这些协议可以处理寻址和路由信息...
  • 音乐类型及不同风格音乐的代表

    万次阅读 2014-04-10 15:23:43
    trip-hop是英伦/欧洲跳舞音乐的一种,它的名字来源是“ trip+ hip hop"= trip-hop",因为它发源自英国的bristol,因此最早时称作"bristol hip-hop".。由于把把hip-hop(其实很多音乐都是架构在hip-hop上的。..不知啥...
  • 问题:今天拿security做权限控制的时候,出现了...重点感谢一个大佬给我提了一句,我这个可能不是重定向到首页,而是重定向到登录前的页面了。 经检查后发现产生这个问题的原因是我项目启动默认访问路径就是 http:
  • 今天我们来聊一聊Android系统的历史,首先我们就要先来说说Android系统这个名字的来历。Android这一次最先出现在法国作家利尔亚当在1886年发飙的科幻小说《未来夏娃》中,作者将外表像人类的机器起名为Android,这也...
  • 一个成功的Git分支模型

    万次阅读 2011-09-21 22:15:20
    能力所限,本文的翻译多处都很不地道,如果哪些地方难于理解,还烦请查看原文。—— Dbzhang800 20110921 在本文中,我向大家介绍的是在大约一年前我为自己的项目(包括工作和私人项目)引入的且已被证实非常成功...
  • 成功的背后!(给所有IT人)

    万次阅读 多人点赞 2014-10-27 00:12:01
    成功的背后,有着许多不为人知的故事,而正是这些夹杂着泪水和汗水的过去,才成就了一个个走向成功的普通人。  凌晨两点半,早已习惯了一个人坐在电脑前的我,望着屏幕,任思绪在暗夜的包容下静静流淌,时光仿佛又...
  • [计算机名人]8位

    万次阅读 2014-06-10 18:24:20
    很多朋友和我说那只胖企鹅不配代表Linux操作系统,因为他们从来没见过一只愤怒的企鹅以超过100迈的速度向他们发起攻击 7. “Intelligence is the ability to avoid doing work, yet getting the work done.” ...
  • 个体户认证微信公众号时,提示 工商数据返回:“企业不存在或企业信息未更新”,法定代表人验证失败。 遇到这种情况该怎么办呢? 个体工商户认证流程 1.准备资料:个体执照、运营者身份证、公众号简介、Logo; ...
  • 想要知道什么人在什么时候浏览了网站的哪些内容吗?查看Apache的访问日志就可以知道。访问日志是Apache的标准日志,本文详细解释了访问日志的内容以及相关选项的配置。 一、访问日志的格式 Apache内建了记录...
  • 目前,作为深度学习的代表算法之一,卷积神经网络(Convolutional Neural Networks,CNN)在计算机视觉、分类等领域上,都取得了当前最好的效果。 后来,基于深度神经网络和搜索树的智能机器人“AlphaGo”在围棋...
  • CPC/CPM/CPA/CPS分别代表什么意思

    千次阅读 2014-09-19 14:31:07
    什么是CPC广告? CPC(Cost Per Click;... ... 但是,此类方法就不少经营广告的网站觉得不公平,比如,虽然浏览者没有点击,但是他已经看到了广告,对于这些看到广告却没有点击的流量来说,网站成了白忙活。很多网
  • 你见过最惊艳的一些 PPT 或者一些演讲者与 PPT 成功配合的案例? 惊艳的 PPT 符合答主的审美观就可以,成功案例分析一下哪里成功,配图 29 个回答 默认排序 ...
  • 安装成功了,但是localhost:8080一直出现404错误,两天了,终于解决这个问题了。由于用mac的人较少,网上资料也很少,所以我将解决办法分享给大家,希望大家少走些弯路,赶快进入php的学习吧! (2)安装成功后,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 233,317
精华内容 93,326
关键字:

代表成功的名字有哪些