java开发,从不同方面提高系统性能

提高系统性能可以从几个方面考虑

 1.JVM虚拟机配置

     JEE容器中运行的JVM参数配置参数的正确使用直接关系到整个系统的性能和处理能力

      1.1.HeapSize 堆的大小

      1.2.GarbageCollector 通过配置相关的参数进行Java中的垃圾收集器的4个算法(策略)进行使用。

      1.3.StackSize 栈是JVM的内存指令区,每个线程都有他自己的Stack,Stack的大小限制着线程的数量。

       1.4.DeBug/Log 在JVM中还可以设置对JVM运行时的日志和JVM挂掉后的日志输出,这点非常的关键,根据各类JVM的日志输出才能配置合适的参数。


2.JDBC

     针对MySQL的JDBC的参数在之前的文章中也有介绍过,在单台机器或者集群的环境下合理的使用JDBC中的配置参数对操作数据库也有很大的影响。 一些所谓高性能的 Java ORM开源框架也就是打开了很多JDBC中的默认参数:

       2.1.例如:autoReconnect、prepStmtCacheSize、cachePrepStmts、useNewIO、blobSendChunkSize 等,

        2.2例如集群环境下:roundRobinLoadBalance、failOverReadOnly、autoReconnectForPools、secondsBeforeRetryMaster。 具体内容可以参阅MySQL的JDBC官方使用手册: http://dev.mysql.com/doc/refman/5.1/zh/connectors.html#cj-jdbc-reference


3.数据库连接池(DataSource)

    应用程序与数据库连接频繁的交互会给系统带来瓶颈和大量的开销会影响到系统的性能,JDBC连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个连接,因此应用程序不需要频繁的与数据库开关连接,并且可以释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

     在此我认为有一点需要说明:

      连接池的使用也是需要关闭,因为在数据库连接池启动的时候就预先和数据库获得了相应的连接,之后不再需要应用程序直接的和数据库打交道,因为应用程序使用数据库连接池是一个“借”的概念,应用程序从数据库连接池中获得资源是“借出”,还需要还回去,就好比有20个水桶放在这里,需要拿水的人都可以使用这些木桶从水池里面拿水,如果20个人都拿完水,不将水桶还回原地,那么后面来的人再需要拿水,只能在旁边等待有人将木桶还回去,之前的人用完后需要放回去,不然后面的人就会一直等待,造成资源堵塞,同理,应用程序获取数据库连接的时候Connection连接对象的时候是从“池”中分配一个数据库连接出去,在使用完毕后,归还这个数据库连接,这样才能保持数据库的连接“有借有还”准则。

      参考资料: http://dev.mysql.com/doc/refman/5.1/zh/connectors.html#cj-connection-pooling

 4.数据存取

    数据库服务器的优化和数据的存取,什么类型的数据放在什么地方更好是值得去思考的问题,将来的存储很可能是混用的,Cache,NOSQL,DFS,    DataBase 在一个系统中都会有,生活的餐具和平日里穿衣服需要摆放在家里,但是不会用同一种类型的家具存放,貌似没有那个人家把餐具和衣服放在同一个柜子里面的。这就像是系统中不同类型的数据一样,对不同类型的数据需要使用合适的存储环境。文件和图片的存储,首先按照访问的热度分类,或者按照文件的大小。强关系类型并且需要事务支持的采用传统的数据库,弱关系型不需要事务支持的可以考虑NOSQL,海量文件存储可以考虑一下支持网络存储的DFS,至于缓存要看你单个数据存储的大小和读写的比例。

     还有一点值得注意就是数据读写分离,无论在DataBase还是NOSQL的环境中大部分都是读大于写,因此在设计时还需考虑 不仅仅需要让数据的读分散在多台机器上,还需要考虑多台机器之间的数据一致性,MySQL的一主多从,在加上MySQL-Proxy或者借用JDBC中的一些参数(roundRobinLoadBalance、failOverReadOnly、autoReconnectForPools、secondsBeforeRetryMaster)对后续应用程序开发,可以将读和写分离,将大量读的压力分散在多台机器上,并且还保证了数据的一致性。

 5.缓存

     在宏观上看缓存一般分为2种:本地缓存和分布式缓存

      5.1.本地缓存,对于Java的本地缓存而言就是讲数据放入静态(static)的数据结合中,然后需要用的时候就从静态数据结合中拿出来,对于高并发的环境建议使用 ConcurrentHashMap或者CopyOnWriteArrayList作为本地缓存。缓存的使用更具体点说就是对系统内存的使用,使用多少内存的资源需要有一个适当比例,如果超过适当的使用存储访问,将会适得其反,导致整个系统的运行效率低下。

       5.2.分布式缓存,一般用于分布式的环境,将每台机器上的缓存进行集中化的存储,并且不仅仅用于缓存的使用范畴,还可以作为分布式系统数据同步/传输的一种手段,一般被使用最多的就是Memcached和Redis。 数据存储在不同的介质上读/写得到的效率是不同的,在系统中如何善用缓存,让你的数据更靠近cpu,下面有一张图你需要永远牢记在心里,来自Google的技术大牛Jeff Dean(Ref)的杰作

6.并发/多线程

    在高并发环境下建议开发者使用JDK中自带的并发包(java.util.concurrent),在JDK1.5以后使用java.util.concurrent下的工具类可以简化多线程开发,在java.util.concurrent的工具中主要分为以下几个主要部分:

     6.1.线程池,线程池的接口(Executor、ExecutorService)与实现类(ThreadPoolExecutor、 ScheduledThreadPoolExecutor),利用jdk自带的线程池框架可以管理任务的排队和安排,并允许受控制的关闭。因为运行一个线程需要消耗系统CPU资源,而创建、结束一个线程也对系统CPU资源有开销,使用线程池不仅仅可以有效的管理多线程的使用,还是可以提高线程的运行效率。

     6.2.本地队列,提供了高效的、可伸缩的、线程安全的非阻塞 FIFO 队列。java.util.concurrent 中的五个实现都支持扩展的 BlockingQueue 接口,该接口定义了 put 和 take 的阻塞版本:LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue、PriorityBlockingQueue 和 DelayQueue。这些不同的类覆盖了生产者-使用者、消息传递、并行任务执行和相关并发设计的大多数常见使用的上下文。

     6.3.同步器,四个类可协助实现常见的专用同步语句。Semaphore 是一个经典的并发工具。CountDownLatch 是一个极其简单但又极其常用的实用工具,用于在保持给定数目的信号、事件或条件前阻塞执行。CyclicBarrier 是一个可重置的多路同步点,在某些并行编程风格中很有用。Exchanger 允许两个线程在 collection 点交换对象,它在多流水线设计中是有用的。

     6.4.并发包 Collection,此包还提供了设计用于多线程上下文中的 Collection 实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList 和 CopyOnWriteArraySet。当期望许多线程访问一个给定 collection 时,ConcurrentHashMap 通常优于同步的 HashMap,ConcurrentSkipListMap 通常优于同步的 TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的 ArrayList。

7.队列

    关于队列可以分为:本地的队列 和 分布式队列 2类

    本地队列:一般常见的用于非及时性的数据批量写入,可以将获取的数据缓存在一个数组中等达到一定数量的时候在进行批量的一次写入,可以使用BlockingQueue或者List/Map来实现。

     相关资料:Sun Java API.

    分布式队列:一般作为消息中间件,构建分布式环境下子系统与子系统之间通信的桥梁,JEE环境中使用最多的就是Apache的AvtiveMQ和Sun公司的OpenMQ。

     轻量级的MQ中间件之前也向大家介绍过一些例如:Kestrel和Redis(Ref http://www.javabloger.com/article/mq-kestrel-redis-for-java.html),最近又听说LinkedIn的搜索技术团队推出了一个MQ产品-kaukaf(Ref http://sna-projects.com/kafka ),对此保持关注。

    相关资料:

    1.ActiveMQ http://activemq.apache.org/getting-started.html

     2.OpenMQ http://mq.java.net/about.html

     3.Kafka http://sna-projects.com/kafka

    4.JMS文章 http://www.javabloger.com/article/category/jms

 8.NIO

    NIO是在JDK1.4后的版本中出现的,在Java 1.4之前,Jdk提供的都是面向流的I/O系统,例如读/写文件则是一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据, 面向流的I/O速度非常慢,并且一个数据包要么整个数据报已经收到,要么还没有。Java NIO非堵塞技术实际是采取Reactor模式,有内容进来会自动通知,不必死等、死循环,大大的提升了系统性能。在现实场景中NIO技术多数运用两个方面,1是文件的读写操作,2是网络上数据流的操作。在NIO中有几个核心对象需要掌握:1选择器(Selector)、2通道(Channel)、3缓冲区(Buffer)。

我的废话:

1.在Java NIO的技术范畴中内存映射文件是一种高效的做法,可以用于缓存中存储的冷/热数据分离,将缓存中的一部分冷数据进行这样的处理,这种做法上比常规的基于流或者基于通道的I/O快的多,通过使文件中的数据出现为内存数组的内容来完成的,将文件中实际读取或者写入的部分才会映射到内存中,并不是将整个文件读到内存中。

 2.在Mysql的jdbc驱动中也可以使用NIO技术对数据库进行操作来提升系统的性能。

9.从程序员开发角度

     9.1.代码程序执行效率,正确实例化对象,申明变量等,避免虚拟机内存资源耗损

     9.2.优化sql,增加合适的索引,正确书写sql,使索引发挥正确的用处

     9.3.java代码开发死循环代码,造成cpu达到100%,致使服务器宕机

长连接/Servlet3.0

 这里说的长连接就是长轮询,以前浏览器(客户端)需要关注服务器端发生的数据变化需要不断的访问服务器,这样客户端的数量一多必然会给服务器端造成很大的压力,例如:论坛中的站内消息。现在Servlet3.0规范中提供了一个新的特性:异步IO通信;该特性会保持一个长连接。利用Servlet3异步请求的这项技术可以大大的缓解服务器端的压力。

 Servlet3.0的原理就是将request的请求开启一个线程挂起,中间设置等待超时的时间,如果后台事件触发request请求,得到的结果返回给客户端的request请求,如果在设置等待超时的时间内没有任何事件发生也将请求返回给客户端,客户端将再次发起request请求,客户端与服务器端的交互可以与此往复。

 就好比,你先过来跟我说如果有人找你,我就立马通知你你来见他,原先你需要不断的问我有没有要找你,而不管有没有人找你,你都需要不断的问我有没有人找你,这样的话不论问的人还是被问的人都会累死。

日志

 Log4J是通常被人们使用的工具,系统在刚刚上线的时候日志一般都设置在INFO的级,真正上线后一般设置在ERROR级,但无论在任何时候,日志的输入内容都是需要关注的,开发人员一般可以依靠输出的日志查找出现的问题或者依靠输出的日志对系统的性能进行优化,日志也是系统运行状态的报告和排错的依据。

 简单来说日志按照定义的不同策略和等级输出到不同的环境,那样便于我们分析和管理。相反你没有策略的输出,那么机器一多,时间一长,会有一大推乱糟糟的日志,会让你排错的时候无从下手,所以日志的输出策略是使用日志的关键点。

 参考资料:http://logging.apache.org/log4j/1.2/manual.html

 打包/部署

在代码设计的时候最好能将不同类型的功能模块在IDE环境中粗粒度的分为不同的工程,便于打成不同jar包部署在不同的环境中。有这样的一个应用场景:需要每天定时远程从SP那边获得当天100条新闻和部分城市的天气预报,虽然每天的数据量不多,但是前端访问的并发量很大,显然需要在系统架构上做到读写分离。

 如果把web工程和定时抓取的功能模块完全集中在一个工程里打包,将导致需要扩展的时候每台机器上既有web应用也有定时器,因为功能模块没有分开,每台机器上都有定时器工作将会造成数据库里面的数据重复。

 如果开发的时候就将web和定时器分为2个工程,打包的时候就可以分开部署,10台web对应一台定期器,分解了前端请求的压力,数据的写入也不会重复。

这样做的另一个好处就是可以共用,在上述的场景中web和定时器都需要对数据库进行读取,那么web和定时器的工程里都有操作数据库的代码,在代码的逻辑上还是感觉乱乱的。如果再抽出一个DAL层的jar,web和定时器的应用模块开发者只需要引用DAL层的jar,开发相关的业务逻辑,面向接口编程,无需考虑具体的数据库操作,具体的对数据库操作由其他开发者完成,可以在开发任务分工上很明确,并且互不干涉。

框架

 所谓流行的SSH(Struts/Spring/Hiberanet)轻量级框架,对于很多中小型项目而言一点都不轻量级,开发者不仅需要维护代码,还需要维护繁琐的xml配置文件,而且说不定某个配置文件写的不对就让整个都工程无法运行。无配置文件可以取代SSH(struts/Spring/Hiberanet)框架的产品真的太多了,我之前就向大家介绍过一些个产品(Ref)。

 这个我并不是一味的反对使用SSH(Struts/Spring/Hiberanet)框架,在我眼里SSH框架真的作用是做到了规范开发,而并不使用了SSH(Struts/Spring/Hiberanet)框架能提高多少性能。

SSH框架只是对于非常大的项目人数上百人的团队,还需要、继续增加团队规模的公司而言,是需要选择一些市面上大家都认可,并且熟悉的技术,SSH(Struts/Spring/Hiberanet)框架比较成熟所以是首先产品。

 但是对于一些小团队中间有个把技术高人的团队而言完全可以选择更加简洁的框架,真正的做到提速你的开发效率,早日抛弃SSH框架选择更简洁的技术在小团队开发中是一种比较明知的选择。

 原文引自:http://blog.csdn.net/u010214269/article/details/50902474

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,050评论 25 707
  • 你有人类的全部美德,却毫无人类的缺陷 ——圣伯纳搜救犬 微博上显示 娜娜是2013年4月27号录入资料库 而救助的...
    武小协干部阅读 591评论 1 1
  • 醒来,感觉面对的世界似乎有点不一样。之前残留在心中的困惑、埋怨在睡梦中远去了一些。突然顿悟到,一个走了那么远的路,...
    周舟阅读与写作阅读 138评论 0 0
  • 一座村落总是会有个标志性的地标,可能幢或古老或新颖的建筑,可能是是棵参天而立的大树,甚至可能是条横穿街巷的河流。在...
    流瓦阅读 372评论 0 1
  • 是 我啊,就是你们口中所说的那类留守儿童。我的童年里几乎没有父母的影子,陪伴我最多的就是爷爷奶奶。小时候,常常会...
    简丹就好阅读 146评论 0 0