近期项目感言

25 八月, 2010 (09:00) | J2ee企业顾问, 杂类 繁体 English    DeliciOus   

在项目中与一国外客户进行接触,这次需要实施的Case是一个基于android平台的智能化人机交互系统,当然这个庞大的系统少不了后端运算的支持,后端计算并且采用了云计算的概念,所以还是少不了J2EE的支持。

在过程中我慢慢的体会到移动计算的市场将会越来越大,越来越丰富。并且智能手机、平板电脑、智能家电、人机交互车载系统的时代已经开启,新的游戏规则被触发,终端用户的操作系统不在是被微软一家独揽。例如 dell现在选择google的android作为自己产品线的平台,云计算逐渐将会更加普及更加密布。

我想所有的javaer开发者们借助云计算的概念和android这样开放式的平台可以飞的更高,可以发开的空间将会更大。

BTW:
真实的人类社会在进步,我想虚拟化的网络社会也会在进步,不知道第二代sns的时代何时到来,也许还会到来更多的市场机遇。

 

–end–

找 lucene 盟友,火拼一项目

24 八月, 2010 (21:29) | 招聘 繁体 English    DeliciOus   

自己朋友(客户)的老系统需要改造,要求对lucene 源码、整个实现机制,包括 lucene 内部架构,对切词、分词 技术 有充分的了解。

并能帮忙我们实现lucene 部分具体的编码工作,和原有的ORM 层对接,实现数据库和索引库同步,压力比较大,工期1-2月,酬劳5位数以上。

联系方式:njthnet # gmail.com

–end–

OpenMQ命令

23 八月, 2010 (22:55) | MiddleWare, OpenSource 繁体 English    DeliciOus   

整理了一些查看OpenMQ JMS Server的 命令,仅供自己参考,学的东西太多,怕忘,先放这里记着。

首先创建一个pasword的文件,这样就不需要每次都 输入密码了,怎么创建,password文件里面的内容,自己看看OpenMQ imqcmd里面的命令也就知道了,这里就不多说了。

查看当前service的运行状态,默认名称是jms
/opt/mq/bin/imqcmd -u admin -passfile pass -b 127.0.0.1:7677 -t q -n jms  query svc

不断的跳动,显示状态
/opt/mq/bin/imqcmd -b 127.0.0.1:7677 -t q -n imagent  metrics dst
同上
imqcmd -b 127.0.0.1:7677 metrics bkr  -m rts  -int 1  -u admin -passfile pass

查看整个服务器的运行属性
imqcmd -u admin -passfile pass -b 127.0.0.1:7677 query bkr 

查看消息队列中的消息
/opt/mq/bin/imqcmd  -u admin -passfile pass -b 127.0.0.1:7677 list msg -t q -n imagent -nocheck

查看消息队列中的连接者
/opt/mq/bin/imqcmd   -u admin -passfile pass -b 127.0.0.1:7677  list cxn

查看整个队列状态
/opt/mq/bin/imqcmd   -u admin -passfile pass -b 127.0.0.1:7677  list dst

查看某个队列的的状态
/opt/mq/bin/imqcmd -b 127.0.0.1:7677 -t q -n  agent 

查询某个消息在某个队列中的状态
imqcmd -b 127.0.0.1:7677 query msg -t q -n agent -msgID "ID:1625-127.0.0.1(ef:f5:f4:5c:46:69)-60828-1282050952257" -nocheck

删除某个队列中的消息
imqcmd  -b 127.0.0.1:7677 destroy msg -t q -n agent -msgID "ID:205-127.0.0.1(83:c2:1d:63:77:b1)-44516-1282050052264" -nocheck

启动 共享 连接
/opt/mq/bin/imqbrokerd -tty -name myBroker -port 7677 -cluster 10.101.102.180:7677,10.101.102.179:7677 -Dimq.cluster.masterbroker=10.101.102.179:7677 -Dimq.jms.max_threads=10240 -Dimq.jms.threadpool_model=shared -vmargs "-Xms6144m -Xmx6144m"

启动 连接
/opt/mq/bin/imqbrokerd -tty -name myBroker -port 7677 -cluster 10.101.102.221:7677,10.101.102.235:7677 -Dimq.cluster.masterbroker=10.101.102.221:7677 -Dimq.jms.max_threads=10240 -Dimq.jms.threadpool_model=shared -vmargs "-Xms6144m -Xmx6144m"

 

–end–

重谈GlassFish服务器优化

23 八月, 2010 (22:50) | GlassFish, Performance 繁体 English    DeliciOus   

Glassfish 优化参数对与我们的团队来说真是"老歌老调,老调重弹啊",不过最近又有一些小小的新发现,废话少说,切入正题。

JVM部分

SUN官方对GlassFish的JVM内存分配 给出了足够详细的定义,并且明确指出  32位、64位 每种不同的操作系统内存分配多少,并不是你的服务器内存多,就可以分配的越多越好,我们后期经过一番压力测试,发现果然如此,将分配到8G,还不如3G的效果好,同学们,这个又是一次教训啊,任何事情不可以想当然的去干,还是需要根据约定的规范来,此外还建议需要打开以下参数,

     <jvm-options>-Dcom.sun.enterprise.server.ss.ASQuickStartup=false</jvm-options>
     <jvm-options>-XX:+AggressiveHeap</jvm-options>
     <jvm-options>-XX:ParallelGCThreads=16</jvm-options>
     <jvm-options>-server </jvm-options>
     <jvm-options>-Dsun.rmi.dgc.client.gcInterval=3600000 </jvm-options>
     <jvm-options>-XX:+DisableExplicitGC </jvm-options>

Sun官方建议的配置参数,如下:

http://1aqpcg.bay.livefilestore.com/y1p0z7K2UdFDJUnQtts43d3C-30a0qpSzkmZ70TYToBVTyAl0zCudNDScjxIcGsmM7ro0gZv9PzYsvyGD0zozjsf7LHL2mnSG2T/glassfish-jvm-size.png?psid=1

thread部分
max-thread-pool-size="32"建议一般设置为 32,太大将会导致 GlassFish一启动的时候就报 Too Many Open File 的现象

HTTP acceptor threads  这个参数设置起来跟你服务器上的CPU个数有关,一般是默认的状态为1。

http部分
max-connections="10240"  这个参数对Keep Alive的 Http场景特别有用,而且越大越好,10000以上都可以。

其他相关配置以前的文章都有介绍,更多的资料还是参考SUN官方的GlassFish优化手册,http://dlc.sun.com/pdf/819-3681/819-3681.pdf  官方手册

 

–end–

 

MySQL JDBC中autoReconnectForPools的用途

23 八月, 2010 (22:21) | Database, Performance 繁体 English    DeliciOus   

有一个这样的场景,2台mysql数据库同步,正常的情况下一般只会连接其中的一台,如果其中一台down掉以后,应用程序能自动连接到另外一台,这样的场景和我上一篇文章描述的有所不同,详见:《MySQL JDBC 集群》一文,前面提到的是轮询访问,现在是一直访问一台,直到另外一台down机以后将会自动切换到另外一台上去,当然实现这样的场景你的应用程序必须使用JDBC的数据库连接池才会有效。

其实MySQL关于集群 的 JDBC参数还有很多,下面这些参数是我从MySQL官方网站上杂录的一部分,提供大家参考,

High Availability and Clustering. 

Property Name Definition Default Value Since Version
autoReconnect Should the driver try to re-establish stale and/or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly. Alternatively, investigate setting the MySQL server variable "wait_timeout" to some high value rather than the default of 8 hours. false 1.1
autoReconnectForPools Use a reconnection strategy appropriate for connection pools (defaults to 'false') false 3.1.3
failOverReadOnly When failing over in autoReconnect mode, should the connection be set to 'read-only'? true 3.0.12
maxReconnects Maximum number of reconnects to attempt if autoReconnect is true, default is '3'. 3 1.1
reconnectAtTxEnd If autoReconnect is set to true, should the driver attempt reconnections at the end of every transaction? false 3.0.10
retriesAllDown When using loadbalancing, the number of times the driver should cycle through available hosts, attempting to connect. Between cycles, the driver will pause for 250ms if no servers are available. 120 5.1.6
initialTimeout If autoReconnect is enabled, the initial time to wait between re-connect attempts (in seconds, defaults to '2'). 2 1.1
roundRobinLoadBalance When autoReconnect is enabled, and failoverReadonly is false, should we pick hosts to connect to on a round-robin basis? false 3.1.2
queriesBeforeRetryMaster Number of queries to issue before falling back to master when failed over (when using multi-host failover). Whichever condition is met first, 'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an attempt to be made to reconnect to the master. Defaults to 50. 50 3.0.2
secondsBeforeRetryMaster How long should the driver wait, when failed over, before attempting 30 3.0.2
selfDestructOnPingMaxOperations =If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connnection's count of commands sent to the server exceeds this value. 0 5.1.6
selfDestructOnPingSecondsLifetime If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connnection's lifetime exceeds this value. 0 5.1.6
resourceId A globally unique name that identifies the resource that this datasource or connection is connected to, used for XAResource.isSameRM() when the driver can't determine this value based on hostnames used in the URL   5.0.1

–end–

 

公司招聘(长期有效)

12 八月, 2010 (11:39) | 杂类 繁体 English    DeliciOus   

要求:
1、Java基础良好,无需懂任何Java框架技术,
2、Linux基础良好,无需了解所有Linux应用服务器,略懂MySQL
3、能吃苦,不浮躁。
4、工作一年或者应届毕业生

工作地点:南京
工作时间:每日7小时、每周五天工作时间
公司规模:1000人左右
薪水:3000-5000
机会:国外项目有出国出差的机会、每年四次加薪机会

福利:
1、每年2次国内旅游,
2、季度一次项目奖金、
3、每天提供免费早餐、免费晚餐和午餐补贴、
4、提供交通补助,
5、每年一次体检、
6、每月购买专业图书可按比例报销、
7、季度吃喝腐败,户外互动一次、
8、每月有1天可不来上班,不扣工资,时间自由支配,
9、每周星期三可参加户外体育锻炼,
10、每季度公司支付费用给部门进行技术培训,强化员工专业技术水平。

联系方式:njthnet#gmail.com

 

百万级 大型J2EE Push Mail 项目后记 3

11 八月, 2010 (23:41) | Architecture, J2ee企业顾问 繁体 English    DeliciOus   

自从1998年 Google 利用廉价的互联网计算机,以最快的速度提供最精确的搜索结果, 这一创新技术成功地缩短了响应时间,提高了可扩展性,并降低了成本。是当今众多公司一直在效仿的技术。在这一项目中完全采用低廉的硬件投入,期望能通过软件的手段、利用分布式计算、集群技术 达到高效的计算,并且能加强系统的可扩展性,提高系统软硬件资源的使用率, 降低系统运行中瞬间的瓶颈。

通过这个项目让我们充分的认识到一个用户的系统 例如:单用户的 OutLook 和 一个百万级的系统的是截然不同的,系统中仅有100条数据和100w条数据的系统更是截然不同的,从100w条数据上升到上亿条数据那样的系统更会让人感受到无论从代码结构、数据库设计还是从系统架构都是完全不同的设计。

客户端环境
    MKT    SDK
    C        语言开发环境   

服务器端环境     
    Apache2            Web服务器
    mod_proxy        Web负载均衡模块   
    HAProxy             前端、数据库负载分载(后期使用)
    Java EE1.5        语言开发环境
    Jboss 4.0.5 GA    应用服务器
    Jboss MQ        JMS服务器
    MySQL  5.1.4        数据库服务器
    EJB 3.0            Java 开发API 工具
    iBATIS            Java 开发API 工具
    OsCache            缓存组件
    Gluster DFS        分布式文件系统
    Nagios            系统监控、报警工具
    Qmail              1台发送邮件服务器

压力测试工具
    Apache Jemter
    Apache AB

当前运行状态
    每月大约有4000多新注册用户
    当前注册大约用户数量200-300w
    每天大约有90-110w用户登录
    每天大约接收500-700W 封邮件
    每天大约接收附件3-5G,超过5M以上的附件将不接受
    每天数据库增加 2W条记录
    每天数据库接受 700W 次请求
    每秒并发最大18000个请求

整体架构

概览
总体上概括,系统分为 1客户端,2服务器端,3SP Mail Server 端,4 CRM 端   下面将讲述整个系统的概况。

后端发送邮件实现过程

1.手机客户端通过http网络协议发送XML数据到服务器端,

2.服务器端接收到xml数据进行解析,服务器端传输层的web请求模块将xml 协议解析,并且重新包装成pojo 对象,

3.中间有一个业务模块分发器将 获得pojo对象交给不同的业务模块进行处理,如:DAL层、消息中间件,

4.将处理完成的业务通过业务模块分发器包装成xml报文回送给客户端。

整个业务处理组成部分如图所示:

 

内部业务逻辑

1.定时器从数据库装载帐户,采用多线程实现一个线程池,我们称这个玩意儿叫做任务工厂,

2.定时向JMS服务器中不同的消息队列发送消息 ,消息接收端收到消息后驱动业务模块去 SP Mail Server  收取邮件,

3.收邮件模块 上SP Mail Server  获取邮件列表头信息,并且和数据库中已存在的邮件列表头信息进行新邮件比对,

4.收取新邮件并且将邮件信息保存到数据库或者缓存,当用户需要读取的时候将从系统的数据库或者缓存中读取,

5.保存完毕后,将通过IP Push 或者 SMS Push 技术 通知用户上服务器获得新邮件。

后端内部架构

Web层
用户的所有请求都是从web层进入,最上层是apache将请求分载到每台AP 服务器 Jboss的web容器上,web容器请求处理用户提交的各种xml请求协议,并且回送处理结果xml协议给客户端,apache经过几次优化并且开了20个进程处理用户所有请求分发,另一台apache standby 通过 heartbeat做备份,如果apache server1失效 将会自动转移到 apach server2上去。在项目后期我们采用HaProxy来替代了Apache的转发工作,也许2者进行优化后的功效相差不了多少,但是我们认为HaProxy安装、移植、部署 比Apache更加方便,最高可以处理2.7W的并发请求处理,并且可以采用leastconn 负载均衡算法,将当前连接请求数量最小的服务器进行命中。

任务调度
检测用户的新邮件功能依赖系统中的任务调度模块,我们管这个模块叫做任务工厂,他先从数据库中装载账户,再放入缓存中,每3分钟装载所有账户一次,向JMS服务器发送消息请求新邮件检查。
从缓存中读取是为了降低数据库的压力, 因为这样的操作太频繁了而且数据量越来越大,会导致数据的压力增大。任务工厂是系统中非常重要的模组,如果任务工厂停止工作将不能检测到所有用户的新邮件, 整个Push Mail系统将会瘫痪,所以必须能支持压力分载和失效转发的功能。

BTW:任务工厂模块最开始在demo的时候采用Quartz 放入Spring微容器中进行集群,因为不能从缓存中直接读取,将来系统账户会越来越多,导致数据库那边的压力越来越大,所以后期我们用 线程池+oscache集群技术 自己开发了一套类似 Quartz+spring集群的方案。另外,这个项目发生在没有Memcached的年代,如果当时使用Memcached也许设计上会更加完美些。

分布式应用
国外用户使用邮箱账号多数都是以 Gmail、AOL、Hotmail、Yahoo 4大邮箱为主,所以我们将处理邮件具体操作的机器分为4组,每组机器处理具体不同的邮箱账号的邮件存取,将整个业务中负荷最大的部分进行分散,独立计算, 每组中的服务器都支持 失效转发和压力分载。
 

EJB消息驱动Bean /JMS  消息系统
系统多线程的定时器,将系统中所有用户帐号装载后由多个JMS发送端发送Queue消息到不同的消息队列,例如:Gmail消息队列、AOL消息队列、Hotmail消息队列、Yahoo消息队列,然后接收端将接收不同的消息队列发送过来的消息,通常我们每组消息队列使用一个发送端对应多个接收端,每组接收端,例如:接收到一批Yahoo账号的JMS消息,将会由多个接收端,例如:接收到一批Yahoo账号的JMS消息,接收端将通过消息分发给不同的计算机组,JMS服务器端采用集群技术,2台JMS服务器上建有4个消息队列,不仅可以进行压力分载,还可以进行失效转发。将4大邮箱分为4个业务群组,每分组各4台消息接收端,一共16台,加上JMS MOM 消息中间件服务器一共18台,在得到上层模组传送过来的指令后,16台专门进行用户邮件解析、发送的操作。

数据库
8台 16 GB内存 、4个CPU 的机器作为 我们使用的MySQL数据库,每台MySQL数据库都安装了XtraDB MySQL插件,主要提高MySQL innodb引擎的读写性能,对于MySQL的整体性能我们主要还是通过调整MySQL的内部参数来进行优化。MySQL原本算使用 NDB引擎来做数据同步和单点失效的,经过实际情况我们反复比对还是使用传统MySQL数据同步来完成我们预想的效果,因为MySQL的集群在我们当时还不算很成熟,而且这玩儿比较消耗内存。

分片(sharding)
每个用户的请求都包含一个用户的ID,我们将判断不同的用户ID到不同的数据上进行操作,当然我们也不是每张表都做拆分,由于用户越来越多我们只把邮件相关的表进行拆分,例如:邮件列表、邮件内容、邮件附件表 3张表近拆分。每张表中都有用户ID这个字段,DAL层根据用户 ID 进行判断 数据的路由规则到具体对应范围的数据库进行存取数据,比如ID在1-10000之间的用户对应到数据库1, ID在10001-20000范围对应到数据库2,以此类推,但是不能在不停机的状态下动态添加数据库服务器节点,后来我们想了一个办法,添加节点的时候通过JMS消息通知每个机器上的DAL层重新读取数据路由配置一次,系统中的数据需要和系统中的CRM系统相结合,后期我们又建立了一个全局数据库(global),这个全局数据库只作为数据索引,为了将所有数据同步,操作所有数据库的记录通过JMS消息定时向全局数据库(global)进行批量操作,如果每笔执行同步操作,将会降低系统性能。

分布式文件系统(DFS)
用户邮件的所以邮件附件都保存在 分布文件系统 前期我们采用Gluster,后期我们采用了MooseFs搭建 使用分布式文件系统是为了能满足我们2点需求 1、由于系统用户不断的增多,导致我们需要保存的邮件附件不断增长,我们需要可以做到当磁盘容量不足时在不停机的情况下无限的添加存储的容量,并且操作方便。2、对于保存的数据可以实时同步,防止单点失效,数据丢失。

JavaMail
我们将Sun  JavaMail 的源代码进行改写,提高收邮件的效率,这样我们在代码中向POP3邮件服务器发送一个命令,立刻在瞬间可以获得上千份邮件的MessageID的头信息。可参见 《修改源码提高JavaMail比较新邮件效率》一文中提到的具体技术。发送邮件采用的是Apache 的 Commons email来简化发送邮件的操作。

 

经验与教训

1.HAProxy的扩展使用,不仅仅可以使用在Web方面,还可以使用到其他应用层,进行压力分钟, 例如,可以应用到 数据MySQL。可以参考这篇文章,http://www.alexwilliams.ca/blog/2009/08/10/using-haproxy-for-mysql-failover-and-redundancy

2.JVM的优化是任何大型J2EE项目中必不可少的话题,当然并不是你把JVM的内存使用空间设置的越大越好,SUN的官方网站已经指出,不同的操作系统,不同的应用,建议你的JVM内存分配大小是不同的。另外,对与不同的JVM也有不同的参数配置,通常的JVM配置参数可以参见这里,http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

3.Linux系统上的swap 空间,4G和4G内存 以内的机器还是非常有必要使用swap空间的,有一次有一个应用服务器系统down机,花了很久的时间才发现,居然是忘记建立Swap空间,多么简单的问题啊,可是把我们折磨了3个星期,3个星期里被老板和客户骂的惨不忍睹,血的教训,让我们再也不会忘记小内存机器建立swap空间了。

4.Jboss MQ的抱怨,首先声明我不是在给Apache 的JMS做广告,因为JbossMQ实在是不好用,而且性能也不咋地,我看见有一篇文章说到JbossMQ的性能在同类产品中是最好的,不知道结果是怎么来的,还是建议大家还是使用Apache的JMS,文档全面啊,不懂就可以找到很全面的资料,jboss MQ 资料的支持不多。

5.MySQL的优化,MySQL的一些参数调优就不说了,但使用MySQL 插件以后给我们带来了不少性能上的提升,特别是在数据查询上的瓶颈可以得到不少缓解。

6.MySQL集群,这玩意儿是个不错的解决方案,可是没有足够的内存是玩不起的,因为MySQL的集群因为完全依赖内存,另外对表的字段也有特别的限制,用起来有点不太自然,不支持所有大字段的类型。如果是老系统迁移过来,估计要折腾一段时间才能合用。

7.JMS 消息的使用,不需要放入数据库,将消息内存当中,并且对JVM运行参数进行优化 ,对与客户端的代码也需要进行优化,关闭消息id (setDisableMessageID),减少消息的大小并且 省去了创建唯一ID的时间。关闭消息的时间戳。如果不需要时间戳,用MessageProducer的setDisableMessageTimeStamp()方法将其关闭。避免使用AUTO_ACKNOWLEDGE。 AUTO_ACKNOWLEDGE  使得每收到一个消息就要向服务器发送一个通知--这样增加的网络传输的负担。如果可能,尽量使用 DUPS_OK_ACKNOWLEDGE或者CLIENT_ACKNOWLEDGE。或者使用事务性会话,将通知在提交时批量完成。
 

口水:
1、上述文字的不牵涉到任何公司,任何技术团队的机要信息纯属虚构,如有雷同,纯属巧合

2、上述中也设计不足的地方,请大家一一指出,谢谢您的阅读与点评。

 

相关文章:
百万级 J2EE Push Mail 项目后记2
百万级 J2EE Push Mail 项目后记
 

–end–

Spring+Webwork整合 NoSuchMethodError 错误

5 八月, 2010 (23:45) | J2EE FrameWork, OpenSource, spring3 繁体 English    DeliciOus   

Spring+Webwork整合也是一个不错的选择,但是当你出现这个错误的时候,也许你以后花了很久还没有找到问题的根源,因为你肯本不会想到是webwork的源代码出了问题,出错的效果如下列所示:    
 
严重: Exception starting filter webwork
java.lang.NoSuchMethodError: com.opensymphony.webwork.spring.WebWorkSpringObjectFactory.setUseClassCache(Z)V
at com.opensymphony.webwork.spring.WebWorkSpringObjectFactory.init(WebWorkSpringObjectFactory.java:63)
at com.opensymphony.webwork.dispatcher.DispatcherUtils.init(DispatcherUtils.java:149)
at com.opensymphony.webwork.dispatcher.DispatcherUtils.<init>(DispatcherUtils.java:83)
at com.opensymphony.webwork.dispatcher.DispatcherUtils.initialize(DispatcherUtils.java:64)
at com.opensymphony.webwork.dispatcher.FilterDispatcher.init(FilterDispatcher.java:130)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4356)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)

http://1aqpcg.bay.livefilestore.com/y1pVWe6ObXFlBSXsVBZqs0lUdMYAzZrEABLP_2QhDaC-vhfHuIYs244G41_6z_mMz1hn7VQzoWaz690y4cENcH5NlZnA2KPv75c/webork-spring-err.jpg?psid=1

查看大图请点击这里

解决方法:

删除   xwork.jar (webwork-2.2.x 版本) 中 的 com/opensymphony/xwork/spring/SpringObjectFactory.class 程序

然后在你的工程中再新建一个SpringObjectFactory.java ,可以从这里下载   要替换的程序,可以不放在xwork.jar中,直接在工程中 编译后和以前一样运行,现在你可以继续使用Spring+Webwork ,世界又恢复平静 。
 
口水:
最近每天事情很多,很想再把 push mail 的第三部写完,主要想说 EJB 、JMS集群、数据库散列

MySQL JDBC 集群

3 八月, 2010 (12:53) | Database, Performance 繁体 English    DeliciOus   

如果按照网上大部分提供的资料,写成这样 url = jdbc:mysql://127.0.0.1,192.168.20.211/dbName仅仅只是用逗号分隔开,那是肯定不行的,当写在jdbc url地址中前一台的数据库(127.0.0.1)down掉以后,就算你重新启动还是会出现org.apache.jasper.JasperException: java.lang.NullPointerException 空指针异常,如图所示
http://public.bay.livefilestore.com/y1p6uh5d_sMRfrT1hDVDnzs53_p41YNSRHbZlu4Ng43R4FdIebI1MtUENYBn-PN0inhz6aGR5_xVc0G6ahK61QbRQ/jdbc-cluster-err.jpg?psid=1

查看大图请点击这里

采用较新版本的 mysql-connector-java-5.1.6.jar  MySQL JDBC 驱动,再将url写成这样url=jdbc:mysql:loadbalance://127.0.0.1,192.168.20.249/dbName
会将访问的压力分载到 127.0.0.1,192.168.20.211 2个机器上,还可以加上roundRobinLoadBalance=true参数,使用roundRobin算法,若是其中一台机器down掉以后,将会自动将不能访问的数据库服务器 踢除,如果还原后将继续进行压力分载。

测试方案:
1、你可以找2台数据库,保证这2台数据库的用户名和密码一致,然后建立2张同样的表,里面插入不同的数据,再通过web程序调用,你不断的刷新页面你将会看见 显示不同的数据,这样就说明 压力被分载到不同的数据库服务器上了。
 
2、再将关闭其中一台服务器,看看是不是会 剔除 被关闭的那台机器直接访问目前活动的那台。

3、如果再恢复,MySQL JDBC 驱动将会帮你 继续分载压力,呵呵。

口水:
Mysql JDBC 驱动的版本也非常的重要 ,建议使用 mysql-connector-java-5.1.6.jar 或者以上的版本。

–end–
 

百万级 J2EE Push Mail 项目后记2

1 八月, 2010 (00:58) | J2ee企业顾问 繁体 English    DeliciOus   

上一篇文章<百万级 J2EE Push Mail 项目后记> 说到了该项目的一些基本概况,这篇日志将讲述一些在开发过程中的与其他团队发生的故事。

这个 Push Mail 项目留给我最深的影响就是给我们团队来了丰厚的利润,客户他是一个美籍印度佬,就是我们常说的那种有钱人,做事爽快、干脆,也是全球移动领域具有影响的专家,因此他要求我们提供的服务必须是具有一个国际化专业水准的团队(International  Corporate)。所谓专业化的主要需要体现在 1执行规范、2执行效率、3执行细节 这3个重要的环节上。

在项目实施过程中除了搞J2EE 的开发者, TA、QA 、SA、DBA  一个也不能少。
1、TA 小组根据制定的项目执行规范监管我们每个开发成员 在每个stage和里程碑的执行力,从需求分析的文档编写规范一直到最后的项目交付,他们才算结束使命。

2、QA 测试团队在我们需求和概要设计 就开始对jboss和mysql其他几项技术学习,其中测试人员与我们一同参与需求分析,这样将来他们才知道该如何配合我们做各种测试,进行深入的测试,而不是我们在引导他们在测试,他们100%能知晓业务 并且制定出不同的测试计划。并不是依靠我们自己测试或者我们在指导他们测试,那样运动员和裁判员都是同一人,那样肯定出问题。

3、SA 的压力最大 需要对系统整体的架构进行设计这个都是分内的事情,更重要的 在真实生产的环境遇到致命性错误,可以回退或者拿出现成的备份方案,把问题在短时间内化解。

4、DBA  需要从高往低的系统架构层次进行对数据库设计与整体规划,必须根据客户需求设计出具有远景的 方案,不是一成不变,更不是所谓“一步到位”的规划设计,是根据预计的数据增长 进行实施规划的不同方案。

5、开发者们需要对每个业务模块都要详细了解。因为我们需要降低风险 开发者们如果出现有人家里有事或者生病 任何一个成员都可以替代,不会出现我今天不来上班,导致项目进度拖慢一天的现象。

在产品在设计开发到发布的过程中,我们分为四个阶段  prototype、demo、stage、producting

prototype 是一个原型,主要完成核心的部分,完成核心的功能和业务逻辑,开发团队内部评估使用。

demo 阶段是将产品的主要部分演示给客户看,让客户确认主体的方向。

stage 根据项目计划分为多个不同的stage版本,每个stage阶段的版本都会在stage服务器上由我们 测试人员先测试5-7天,再发布到真实的生产环境中。客户对这样的流程要求的非常的严格。因此 stage 服务器的配置和数量与 producting 环境是100%相同的,没有他们的邮件确认我们是不能擅自发布到 producting 环境中的,如果 producting 环境出现问题,必须在短时间内能回归到上一个稳定版本的状态 。 后期会在 stage producting 服务器上轮回 ,fix –> testing —> release。

我们当时使用SVN和Trac,值得一提的是Trac这个东西,客户有任何需求变更 通过 Trac 系统 TA,QA,DBA,SA  统统都会知道,并且知道我们会在下个版本 什么时候 会  发布在stage 服务器上,我们也能在第一时间知道他们对 当前版本的 性能情况,客户也能看见但似乎他们并不在意这个结果,因为他们需要知道我们当前的执行状态是否符合计划,其实TA的成员比他们更加关注我们的项目进度,呵呵。因此,所有人的开发进度执行情况都在trac上进行展现。客户也可以看见,也可以回复,所有信息所有人同步。

呵呵,另外那三十几台需要发布应用程序的机器,分别发布不同的应用程序或者不同的版本不可能完全依靠人工完成,我们需要一个半自动化的工具帮助我们完成,所以我们选择了hudson和自己编写的liunx脚本。这样可以提供效率,并且大大减少了发布时出错的机率。

先写这么多,有什么忘记的地方我回头补上,下一篇将开始 讲述 技术方面的那点事儿了。


口水:

不想说的太多,怕泄露机要,言多必失。

以上文字 如有雷同,纯属巧合,私下讨论,倒是可以。

 

–end–
 

-->