<< 二月 2013 | 首页 | 四月 2013 >>

java - Difference between Jax-ws, axis2, cxf - Stack Overflow

JDK1.6 已经绑定了JAX-WS的实现,webservice开发可以不需要任何第三方的jar依赖,特别是webservice客户端,通过wsimport工具或者手工编写客户端即可完成。

What is the difference between JAX-WS, axis2, cxf? All three can be used to create webservices in java.As of i know JAX-WS is a specification and axis2 and cxf are implementations. But Java 1.6 has implementation of JAx-WS if i am not wrong. So one can use java 1.6 to develop jax-ws web services without using axis2, cxf? Then what is the use of axis2, cxf?

 

The JAX-WS implementation built into the JDK really is just the basic soap stuff. If you need any of the more complex WS-* things like WS-Security, WS-RM, WS-Policy, etc..., you need to use one of the alternatives like CXF or Metro or Axis2. It can also depend on what you are trying to integrate with. For example, CXF has top notch Spring support as well as very good OSGi support.

CXF also has other things besides just JAX-WS. It has a compliant JAX-RS implementation as well and supports exposing services as both REST and SOAP very well. Has a W3C compliant SOAP/JMS implementation if that type of things is required. Basically, lots of stuff not available from the in-jdk JAX-WS impl.

Also see:

Difference between Apache CXF and Axis

 

阅读全文……

标签 : ,

常用旅游英语口语

 路试常用英语大全

 

Good Morning Sir/Madam 先生/女士 早晨好 

Good Afternoon 午安

How are you? 你好么

Do you speak English? 你讲英语吗?

I can speak a little English. 我可以讲一点英语

Please speak slowly. 请慢慢讲

Would you mind speak louder please? 请讲大声一些

Do you wear glasses? 你有戴眼镜么?

I wear contact lenses. 我戴隐型眼镜

Do you live at same address? 你住在上述地址么?

Do you have any medical problem? 你的健康有问题么?

Do you have any question? 你有什么问题么?

You must obey all the rules and traffic signs.你要遵守所有的交通规则和标志

Please sign your name here. 请在这里签名

Are you ready now? 你准备好了么?

Turn on the engine (car). 点火

Let's go. 现在开始

Right turn. 右转

Left turn. 左转

Go straight/keep moving straight. 直行

First street right turn/left turn. 第一条街右转/左转

Traffic light right turn/left turn. 交通灯右转/左转

Stop sign, make a right turn/left turn. 停牌右转/左转

Stay in this lane. 保持在这条线路行驶

Second street. 第二条街

Turn on the headlights. 开车头灯

Turn on the wind shield wiper. 开雨刷

Right of way. 优先权

Stop the car here. 在这里停车

Pull over the curb. 靠路边停车

Slow down 慢驶

Three point turn. 三点调头

Parallel parking. 平行泊车

Up hill parking. 上坡泊车

Down hill parking. 下坡泊车

Back up. 后退

Back into the driveway. 倒车进入车道

Too close. 太接近

Too slow. 太慢

Too fast. 太快

Speed up . 加速

Give your signal. 打灯号

Cancel your signal. 取消灯号

Try again. 再试一次

Watch for pedestrians. 注意行人

Take it easy/relax please. 请不要紧张

More gas. 加油

Follow the car. 跟着前车

Go back to the test centre. 回考试中心

Entrance. 入口

Exit 出口

Intersection 十字路口

Put on your seat belt. 放安全带

Parking brake . 手刹

Turn on the heater/air conditioner. 打开暖气/冷气

Head in parking/drive in . 车头进泊车

Back in parking. 后退泊车

Turn off the engine. 关闭引擎

You failed. 你不合格

Do you have any identification? 你有证件么

You passed. 你通过

Try again. 下次再试

阅读全文……

标签 : , ,

探查 JDBC Multipool 问题

负载平衡算法
采用负载平衡算法的 MultiPool 以 Round Robin 方式提供其连接,各连接在为其定义的所有 JDBC 连接池之间均匀分布。如果对某个连接的连接测试失败,MultiPool 会尝试从列表中的下一个池中提供连接。以下位置提供了更多详细信息:http://e-docs.bea.com/wls/docs81/jdbc/programming.html#1023962 (English)。

因此,负载平衡既具有在若干个池间分配负载的长处,又能够在其中一个池不可用时提供一定程度的 Failover 能力。不过,如果采用负载平衡算法,将无法控制 MultiPool 响应来自其列表中不同池的连接请求的顺序及其 Failover 的目标池。

MultiPool 的限制
若要为 MultiPool 启用高可用性算法,需要考虑一些限制和前提条件。http://e-docs.bea.com/wls/docs81/jdbc/programming.html#1068130 (English) 中提供了详细信息。下面是对上述要点的总结:
  • 启用 JDBCConnectionPool 上的 TestConnectionsOnReserve(MultiPool 的一部分),以便 MultiPool 可以检测到连接失败及 Failover 到列表中下一个 JDBC 连接池的必要性。
     
  • MultiPool 的名称在域配置内必须是唯一的。不应以相同名称命名 JDBC 连接池和 MultiPool,因为那样会导致 Failover 故障。
     
  • 如果第一个池中的所有连接都处于使用状态,MultiPool 将不会从列表中的下一个池提供连接。只有在 MultiPool 配置中的 JDBC 连接池的数据库发生故障或某个池被暂停使用时,才会提供 Failover。
    不过,WebLogic Server 8.1 SP3 及更高版本中添加了一个新属性FailoverRequestIfBusy,可以通过该属性配置 MultiPool,从而实现当某个池中的所有连接都处于使用状态时,从列表中的下一个池中提供连接。WebLogic Server 版本 8.1 SP3 及更高版本中针对 MultiPool 的增强功能中对此有更为详尽的描述。
     
  • 当某个应用程序从 MultiPool 中得到了一个连接后,在该应用程序使用该连接期间,将不再为该连接执行 Failover。这是因为 MultiPool 在连接测试期间调用 getConnection() 时检测到连接失败。后面阶段出现的数据库故障需要由应用程序处理,其步骤与用于正常 JDBC 连接池的步骤相同。由于数据库崩溃或关闭时会将事务回滚,因此应用程序需要对这种情况进行处理,并重新执行相关工作。

 

java.sql.SQLException: Pool connect failed :
weblogic.common.ResourceException: testMultiPool(myMultiPool):
weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool myMultiPool to allocate to applications, 
please increase the size of the pool and retry..
at weblogic.jdbc.common.internal.JDBCUtil.wrapAndThrowResourceException(JDBCUtil.java:160)

阅读全文……

Using Multi Data Sources with Oracle RAC - 11g Release 1 (10.3.6)

Attributes of a Multi Data Source

The multi data source may have the following attributes, depending on the role of Oracle RAC in your system—load balancing or failover:

  • AlgorithmType="Load-Balancing" or AlgorithmType="Failover"

    With the Load-Balancing option, connection requests are distributed among available data sources; with the High-Availability option, connection requests are served by the first available pool in the list. When a data source becomes defunct, connection requests are served by the next data source in the list.

  • FailoverRequestIfBusy="true"

    With the Failover algorithm, this attribute enables failover when all connections in a data source are in use.

  • TestFrequencySeconds="120"

    This attribute controls the frequency at which WebLogic Server checks the health of data sources previously marked as unhealthy to see if connections can be recreated and if the data source can be re-enabled. For more details see Chapter 5, "Configuring JDBC Multi Data Sources."

    For fast failover of Oracle RAC nodes, set this value to a smaller interval, for example, 10 (seconds).

     

 

阅读全文……

Configuring JDBC Multi Data Sources - 11g Release 1 (10.3.6)

 

Choosing the Multi Data Source Algorithm

Before you set up a multi data source, you need to determine the primary purpose of the multi data source—failover or load balancing. You can choose the algorithm that corresponds with your requirements.

Failover

The Failover algorithm provides an ordered list of data sources to use to satisfy connection requests. Normally, every connection request to this kind of multi data source is served by the first data source in the list. If a database connection test fails and the connection cannot be replaced, or if the data source is suspended, a connection is sought sequentially from the next data source on the list.

Note:

This algorithm requires that Test Reserved Connections (TestConnectionsOnReserve) on the data source is enabled. If enabled, a connection in the first data source is tested to verify if the data source is healthy. If the connection fails the test, the multi data source uses a connection from the next data source listed in the multi data source. See Connection Testing Options for a Data Source for information about configuring TestConnectionsOnReserve.

JDBC is a highly stateful client-DBMS protocol, in which the DBMS connection and transactional state are tied directly to the socket between the DBMS process and the client (driver). For this reason, failover of a connection while it is in use is not supported.

Load Balancing

Connection requests to a load-balancing multi data source are served from any data source in the list. The multi data source selects data sources to use to satisfy connection requests using a round-robin scheme. When the multi data source provides a connection, it selects a connection from the data source listed just after the last data source that was used to provide a connection. Multi data sources that use the Load Balancing algorithm also fail over to the next data source in the list if a database connection test fails and the connection cannot be replaced, or if the data source is suspended.

Multi Data Source Fail-Over Limitations and Requirements

WebLogic Server provides the Failover algorithm for multi data sources so that if a data source fails (for example, if the database management system crashes), your system can continue to operate. However, you must consider the following limitations and requirements when configuring your system.

Test Connections on Reserve to Enable Fail-Over

Data sources rely on the Test Reserved Connections (TestConnectionsOnReserve) feature on the data source to know when database connectivity is lost. Testing reserved connections must be enabled for the data sources within the multi data source. WebLogic Server will test each connection before giving it to an application. With the Failover algorithm, the multi data source uses the results from connection test to determine when to fail over to the next data source in the multi data source. After a test failure, the data source attempts to recreate the connection. If that attempt fails, the multi data source fails over to the next data source.

No Fail-Over for In-Use Connections

It is possible for a connection to fail after being reserved, in which case your application must handle the failure. WebLogic Server cannot provide fail-over for connections that fail while being used by an application. Any failure while using a connection requires that the application code close the failed connection, and the transaction must be restarted from the beginning with a new connection.

Multi Data Source Failover Enhancements

The following enhancements improve failover processing for multi data sources:

阅读全文……

Linode VPS服务器介绍及购买指引

Linode优化建议

  1. 充分利用Linode服务器四核运算能力:榨干服务器,让进程运行在指定的CPU
  2. 简单快捷地备份Linode数据:备份数据库到S3
  3. 系统初装之后,建议进行一次LAMP最小优化
  4. 其他有关Linode的文章

Linode技术支持

Linode很适合作为Linux入门的材料。但对不熟悉shell的朋友,可能一开始安装软件、配置服务器都比较困难。

我提供有偿的技术支持,能解决大部分Linode上的配置问题,以及迁移网站的问题。详细请看:提供Linode技术支持

FAQ

Q:什么样的人适合用linode?

A:由于Linode是Linux的VPS,所以需要有一定的Linux操作功底。当然,对不熟悉Linux服务器的人,也无疑是一次锻炼的机会。我就是在不熟悉Linux的情况下开始用Linode的。

Q:Linode主机价格如何?

A:Linode的VPS是相当价廉的VPS,价格要比Slicehost便宜约30%,比起MediaTemple就更加有优势。Linode的VPS有多种配置,最便宜一款$19.95。年付打9折。所有VPS配置列表可以在Linode首页找到。

Q:使用Linode会不会被墙?

A:每个Linode都有独立IP,这至少可保障你的网站不会被别人牵连。如果自己的IP被墙了,购买一个extra IP需要每个月1美金。BTW,可以在Linode上搭建VPN,极大方便平日流连Youtube、Facebook等资本主义国家的网站。

Q:Linode如何备份?

A:Linode提供了备份服务,但我更建议备份到Amazon S3。我编写了一个备份脚本,可以在Linode上用于备份数据。推荐使用。

Q:购买Linode应如何付款?

A:需要一张支持美金支付的信用卡,Linode不支持Paypal。经过测试,招行信用卡可以成功支付。

Q:Linode服务器速度如何?

A:请看 Linode4个机房的速度比较(杭州电信)。测试方法为单线程在4个机房的服务器上分别下载91M的文件。

机房 速度
Fremont, CA 140.90 KB/s
Dallas, TX 8.33 KB/s
Atlanta, GA 55.65 KB/s
Newark, NJ 141.09 KB/s

测试下载的文件和简要说明在此

可以看到,Fremont机房和Newark机房都是很好的选择。我的Linode选择了Fremont机房,可以在此处实际测试一下服务器的速度(测出的数值除以8就是相应的KB/sec)。

注:最近也有朋友发现达拉斯机房的速度很不错,相比Fremont/Newark要好。所以建议大家购买时,自己实际测试下,选一个表现最好的。

Q:使用Linode如何进行备份?

A:Linode自己提供了backup的服务,按照不同等级的Plan进行收费。如果数据确实很重要,备份到Amazon S3也是个很好的选择。当然,我是把一些重要数据备份到Dreamhost服务器的。一个关键的优势在于:服务器放在国外,不管是连接S3还是连Dreamhost都是飞快,而且没有GFW。

阅读全文……

标签 : ,

Linode VPS 简介和使用指南

Linode VPS 购买教程

1、登录 Linode 官网 ,http://www.linode.com/

2、选择适合你自己的套餐,点击购买。

我选择linode 1024这个套餐,进行下面的购买及支付需要一张支持美元的信用卡,VISA、MASTER Card都可以。国内大部分银行的都可以,我这里使用的招商银行的信用卡。

3、填写基本资料,根据图中的提示填写即可。Linode vpn 套餐注册

Linode 服务器介绍及购买指引

Linode vpn 注册信息填写

如果您觉得本文对您有用处,你可以在购买的时候在Referral Code栏填写: "a396a5bacb1e332ff04e632704ea309036cf4c88"

如果有朋友看了我的文章觉得有用的话,恰好你又要购买 Linode 的 VPS,不妨使用我的 Refer 代码,于己无损,于人受益。

点击“continue”之后,回来到一个信息确认页面,有个协议需要确认,单击小方框,出现小勾就行了。

还有一个需要注意的是,好像不容易买到刚好一个月,比如我26号买的,这个月剩余的5天,我同样需要购买,实际上我支付了1个月15天,共计:23.82美元。事后,后台截图:Linode vpn 付款后台

 

5、上步确认之后,你的Linode vps就购买完成了,手机上也收到了银行发来的信用卡支付信息,同时邮箱也受到订单的信息和帐号激活信息。

阅读全文……

标签 : ,

Examples | Elycharts

Elycharts is the ultimate javascript charting library

阅读全文……

[转]java中判断字符串是否为数字的三种方法 - Javaphua Blog - BlogJava

1用JAVA自带的函数
public static boolean isNumeric(String str){
  for (int i = str.length();--i>=0;){   
   if (!Character.isDigit(str.charAt(i))){
    return false;
   }
  }
  return true;
 }

2用正则表达式
public static boolean isNumeric(String str){ 
    Pattern pattern = Pattern.compile("[0-9]*"); 
    return pattern.matcher(str).matches();    
 } 

3用ascii码

public static boolean isNumeric(String str){
   for(int i=str.length();--i>=0;){
      int chr=str.charAt(i);
      if(chr<48 || chr>57)
         return false;
   }
   return true;
}

阅读全文……

AwesomeChartJS

AwesomeChartJS is a simple Javascript library that can be used to create charts based on the HTML 5 canvas element.

The main goal during development was to pick sane defaults in order to let the user create simple charts quickly with just a couple of lines of code.

One can create at almost no time bar, pie, doughnut and Pareto charts.

 

阅读全文……

标签 : ,

Scratch1.4入门指南(新)_Scratch儿童编程语言_百度空间

Scratch儿童编程语言。

Scratch动画 编程教程截图

阅读全文……

标签 : ,

Add an Expires or a Cache-Control Header in JSP - Stack Overflow

To disable browser cache JSP pages, create a Filter which is mapped on an url-pattern of*.jsp and does basically the following in the doFilter() method:

HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1 httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0 httpResponse.setDateHeader("Expires", 0); // Proxies.

This way you don't need to copypaste this over all JSP pages and clutter them with scriptlets.

To enable browser cache for static components like CSS and JS, put them all in a common folder like/static and create a Filter which is mapped on an url-pattern of /static/* and does basically the following in the doFilter() method:

httpResponse.setDateHeader("Expires", System.currentTimeMillis() + 604800000L); // 1 week in future.

 

阅读全文……

标签 : ,

WebLogic的多池Multi-Pool - 无法无天耗的日志 - 网易博客

客户的做法是这样的:

后台是Oracle的RAC数据库,他配置了一个多池,有2个Pool,PoolA主要连RAC的A实例,PoolB主要连RAC的B实例.其实他的PoolA和PoolB都是用了RAC格式的JDBC的写法,后面是一个主机列表,PoolA将A实例的IP写在了前面,PoolB将B实例的IP写在了前面,JDBC的算法是failover=yes load_banlance=no,这样每一个Pool将请求都发送到自己的第一个host的Oracle的实例上,在第一个host的Oracle实例出现故障时候切换到另外一个host的Oracle实例上.

PoolA和PoolB的JDBC的写法如下,注意failover=yes和load_banlance=yes,这样写的作用是当请求来的时候都转发给第一个host,只有出现第一个host有问题,才会将请求发送到第二个host:

WLS JDBC URL 的配置如下:

jdbc:oracle:thin:@(description=(address_list= (address=(host=172.18.137.231) (protocol=tcp)(port=1521))(address=(host=172.18.137.230)(protocol=tcp) (port=1521)) (load_balance=yes)(failover=yes))(connect_data=(service_name= slrac.bea.com)))

配置的多池的算法如果是High Availability的话,那么压力将始终压到一个Pool上面,另外一个Pool处于stand-by的状态,除非处理请求的Pool出现故障.客户的监控情况也是如此,发现压力都压在了一个Oracle的实例上.

如果多池的算法是Load Banlance的话,那么压力将平均分配到2个Pool上面.如果想使用多池的high availability的算法,则不要设置test的重试次数,如果设置了,则会出错抛出异常.

为了能使被标记为disable的PoolA能够恢复正常的连接,则需要设置HealthCheckFrequencySeconds的值在config.xml里面,该值在console上面没有.

另外还要能够使用TestConnectionsOnReserve.

阅读全文……

标签 :

AppFog免费使用经验

 

 

AppFog是一个推出不久的云计算PAAS平台即服务,是在2012年值得关注的十个云计算服务里排在首位的。本人获悉之后加入了开发者试用行列,首先搭建了用于个人知识管理的网页书签服务。采用的是java平台,根据网上速度评测选择美国西部的机房,代码则是从google app engine原博客项目改造过来。由于担心是否支持数据备份导出问题,我对这个个人知识管理的网页书签服务使用程度比较低,而且最近发现美国西部机房的网络有点慢,甚至很不稳定,经研究发现应该是国家防火墙在作怪。然后,最近我突发奇想注册了一个域名www.BrandsTroy.com,想做一个诉说品牌故事的网站,因为我发现大型商场里很多品牌都是英文的,而且几乎完全都不认识,而在网上查找,也经常没有什么信息,所以做了一个这样的品牌故事汇网站,去发现一些著名品牌和奢侈品,并描述他们的品牌故事。我将这个网站托管在appFog云计算平台上,并将域名绑定上去。下面简单介绍一下appfog的一些使用经验:

 

1、存储和流量配额限制。appfog上每个免费注册账户有2G内存可用,最多可运行8个实例/网站,每个网站最大数据存储100M,50GB月流量。问题最大的是每个数据库实例只有100M,月流量50GB,我分析一下,对于大多数网站来说(包括个人博客、企业网站)应该已经够用了,按照平均每篇文章大小10K计算,最大可容纳1万篇文章信息,每天写三篇文章则可以支撑7、8年运行。而流量大约是每天1.5G,按照每个网页15K计算,每天可支撑11万次访问,可在Alexa全球排名到达3万名以内,看来是足够了。

 

2、万一要迁移,就要面临数据迁移的问题。数据库备份,appfog是完全支持的。通过运行命令行 af tunnel 命令选择数据库实例,然后选择数据库对应的备份工具如mysqldump,输入备份文件名,则可以备份下来。备份下来的mysql数据文件,可以恢复到appfog上其他的mysql数据库实例上或者本地机器的mysql数据库上。

 

3、机房选择。之前看网上评测说美国西部机房网络比较快,经过实际使用测试,得出美国西部的机房非常不稳定(因为国家防火墙的缘故),而且速度其实也很慢。所以经验是,新加坡的机房还算稳定,速度也还行。当然,做网站别存在任何侥幸心理,别放任何违反法律、反人类、政治敏感内容在你的网站上。

 

4、服务维护、日志查看、应用上载,全部都可以通过af工具顺利完成,参考https://docs.appfog.com/getting-started/af-cli

 

5、数据库账户,需要通过af tunnel获得登录数据库名以及账户名和密码,而数据库地址,需要写程序来获得,如java可写一个jsp程序部署上去访问它来得到数据库IP地址信息:

jsp程序内容:

<%

out.println(java.lang.System.getenv("VCAP_SERVICES"));

%>

 

顺便说一句,做这些必须得带着玩的心态,别太认真,国内的环境实在让人不踏实,说不定哪天全没了。

祝你玩得开心!

标签 : , ,

源代码控制管理十戒

 

我还没有见过比源码版本控制这样跨任意编程语言更基本的工具。 这是我们用过的最基本的工具,是很多开发团队的生命线。 那么,为什么我们经常会用错呢? 为什么一些真正的核心,版本控制系统的基础往往知之甚少?

我总结了10个实践 或“戒律” - 这通常是发生故障或错误理解的开始, 是与版本控制产品和编程语言无关的。 我会从Subversion和.NET挑选一些例子,但它们广泛适用于其他技术。

 

1。 如果还在使用VSS,马上停手 

平心而论,在1995年VSS曾是一个伟大的工具。  不过因为有了像Subversion甚至分布式的如Git和Mercurial工具变得黯然失色。 很多年前微软已经明确表明废弃它了!

由于一系列的重大缺陷,VSS曾受到广泛的几乎一致的鄙视, 俗称为微软的源代码破坏系统 。

 Visual Source Safe 2005 boxVSS = a great big steaming pile of shit - JUST SAY NO!

 

2。 如果源代码没有处在版本控制,那等于还没有

每天重复此咒语 - “进步的唯一标准是工作代码处在源代码控制中”。 直到你的成果出现在源代码控制里 - 变成源控制库中的项目 - 否则它根本不存在。

当然,你已经把代码做好在本地计算机上的某个地方,但,对其他人来说这不是真的做好了,对吗? 他们不能拿到你的版本,他们不能合并他们的修改,你无法部署它(除非你部署出错 ),一旦发生硬盘损坏你将永久丢失这些文件。

你要保持除非提交否则根本还没有的心态,一大堆的其他良好的运作因为没有提交开始陷入困境。 你应将任务分解成更小的单位,这样你可以原子地提交。 您应频繁地整合,保证自己不受本地硬件故障的影响。

但更重要的是(至少对你的团队领导来说),你证明你实际做了东西。 燃尽图曲线下降或分解列举任务列表是很棒的,但他们真的顺畅吗? 除非这些与工作源码控制中的工作代码关联上,他们才意味着完成。

3。 尽早提交,频繁提交,越快越好

继续上一点,只有这样,才能避免“幽灵代码” -那些只有你可以在你本地计算机上能看到的代码-要尽快地尽早地频繁提交到VCS版本控制系统里 。 上面提到的是应尽早和经常的完成提交,但其中有几点可以使你的工作方式有意义:

1,每个提交的修订版能给你一个回退的位置。如果你完全搞砸了,你想回滚一个小时的变化还是一个星期的吗?

2,合并噩梦的风险不会显着增加。合并从来就没有乐趣。 当你几天没提交代码时,你突然发现到你已经与其他人的变化有50个冲突,你肯定不开心。

3,它会强迫你将功能隔离在分散的工作单元。比方说,你已经有了一个3人天功能需实现。 通常,因为他们想试图整个地构成一个逻辑单元直到这段时间结束才提交。 当然,像这样大的一个任务不可避免地由小规模,分散的功能组成,频繁提交迫使你识别这些原子小任务,然后逐一地完成它们提交给VCS。

当你以这种方式工作时,你的提交历史形成一个有规律的模式,每天多次提交。 当然,并不总是保持这样不变的模式,有时我们停止开发和重构进入测试阶段,或任何其他中断正常的开发周期的活动。

然而,当我看到一个独特的 - 甚至整个项目,在一个正常的开发周期,有整天甚至很多天什么没提交,我很担心。 我很担心是因为根据之前提到的,没有可衡量的工作已经完成,但我也很担心,因为这通常意味着出问题了。 这意味着,开发像“沸腾的海洋”那样进行(例如,试图一次做所有事情),或根本没有任何价值的事情在发生,因为在所有的人都阻塞在一个问题上。 无论哪种方式都是错的,源代码控制系统正打了个大红色警告。

4。 在提交之前,请务必检查您所做的更改

提交代码到源代码控制系统是很容易的 - 太容易了!无论如何,你总算了结了变更和提交了文件。 “在项目的根目录有一个变更地方 - 快 - 提交了!”

可能会发生一件或两件事情:首先,人们在不经意间上传了一大堆的垃圾文件到存储库中。 请看类似下面的窗口,点击“全选”和确定 - 库不应该被某些文件如调试Debug文件夹和其他垃圾污染了。

A commit window showing a lot of files that shouldn't be in source control

其次,提交文件经常不检查他们实际上已经改变什么。 例如在本地开发一次性修改的配置或项目定义文件,这使得它很容易在不经意间被放到资料库,原本不打算提交的,当然,他们很可能被其他开发者获取。 你真的能记住你改变了这个配置文件中的东西吗?

A commit window showing a web.config file with unkown changes

解决方法很简单: 在提交之前你必须检查每一个变化 。 这听上去很容易,可使用很多版本系统实现的“忽略”功能,在很大程度上缓解“无意中提交文件”问题。 你不想提交Thumbs.db文件,只要忽略它,还有 你可能不想要提交的每一个变更文件!

你经常想知道文件哪个地方修改了,为什么又提交Web.config文件?你可以使用VCS的文件比较Diff功能。

A diff window showing inadvertant changes in the web.config file

啊,我现在想起来,我想减少最大无效密码尝试从5下降至3。 哦,我玩了一个假的登录页面,我绝对不希望提交到库中。 

5。 记得提交时编写提交信息日志,

有了提交日志信息,我可以理解你的提交信息并可通过你的代码试图追踪一个错误。

提交信息的整体思路是解释为什么你提交代码,每次你改变代码,肯定是有原因的。 也许是出了故障, 也许顾客不喜欢配色方案。 也许你只需要调整build配置。 不管它是什么,它是有原因的,你需要在你提交后留下它。

为什么要写日志呢? 根据上下文的不同有几个不同的原因, 例如,使用“责备”功能,或其他类似的功能,它暴露了谁改变了什么以及意图 。 我不记得我在18个月前对这个项目中的Web.config改了什么,为什么我修改应用程序设置,因为我留下了不错的提交信息,这一切都变得非常简单:

A blame log with a descriptive log message

同样地,随着时间的推移变化,无论我是否希望看到的一个文件全部历史记录,如下图,我只是想看看昨天整个团队完成了什么,如有记录描述性的意见,意味着不需要采取更仔细的研究,就能了解这是怎么回事。

A series of well formed commit messages

最后,提交的信息是绝对无价的,当涉及到跟踪错误。 例如,想知道什么打断了持续集成环境。 当然,我的例子是明显而易见的,但有一点是,如果没有这个信息,这将是个棘手的问题。

A descriptive commit message on a failing TeamCity build

 

进一步考虑一下,这里有一些提交信息的反模式:

1.有些事情。

2.它的工作原理!

3.修正了一些该死的错误

4.修复

5.修正一个小错误...

6.更新

7.错字

8.修订1024!

我是从Stack Overflow上问题挑选出来的——你曾经编写的最糟糕的提交信息是什么。 他们没有告诉你代码中实际发生了什么,他们是垃圾信息。

关于提交信息的最后一件事, 来自同一作者的随后提交的信息不应该是相同的 。 原因很简单:你正在提交的原因与上一个版本不同。 你的代码与先前的版本是在一个不同的状态,如果你提交的信息是准确和完整的,应该在逻辑上是不相同的。 此外,如果是相同的(也许有一个合法的边缘情况下),日志变乱了,没有办法辨别两次提交之间的差异。

6。 您必须自己提交更改 - 不能委派

这听起来很奇怪的,因为,它发生过,我见过不止一次,最近一次就在上周。 这里的情况是源代码控制库被放置在控制台机器上。 由于种种原因,该团队将其视为隔离,完美的代码纯净环境。 为了维持这个神圣的状态,代码提交之前需经过小组评审并(推断)调整和改进后才能被首席开发人员提交。

似乎这种模式是很有道理的。 但极少提交,多个开发人员团队只有一个作者,如果长时间没有提交的任何人一旦离开了即无可避免地将造成冲突混乱, 这样非常危险。

有两个重要的事情错在这里:第一源代码控制并不意味着是无暇的,无问题的原始代码;第二没有贯穿整个开发周期。 源代码库是团队整合频繁的地方,当出错时可回滚,团队工作围绕的一个共同的基础。 在整个过程中并不一定是完美的,但它必须(尝试)在应用程序生命周期中的达成发布状态。

另外,从开发者的角度来看, 这种模式是根本没有源代码控制!这意味着没有和同行集成代码,没有回滚,没有日志,什么都没有! 你只是坐在那里,在你的本地写代码,等待未来的任意点手工传给老板。

 

7。 数据库版本控制不是可选的

这是每个人都应该知道的,但很多时候,他们就是由于“很难”而没有做控制。 问题是,许多(大多数?)的应用程序没有数据库将无法运行。 如果你没有版本控制数据库,那么最终是一个不完整的应用程序。

大多数VCS系统的工作原理是在文件系统上的简单地版本化文件。 例如典型的应用程序文件,如HTML页面,图片,CSS,项目配置文件和其他位于文件系统中的分散成小单元的文件。 问题是,这不是关系型数据库的工作方式。 相反,你面对的是这些大的数据文件和日志文件,其中包括一大堆不同的对象和数据。 当涉及到版本控制是相当混乱的。

数据库版本有一些可用的工具,如来自Red Gate的非常优秀的SQL源代码控制工具。 去年我写了这个详细的文章——用Red Gate起舞你的SQL源代码控制世界,所以我不会再深入的细节,我只想说,现在数据库版本控制很容易

说实话,如果现在你没有版本控制那么在开发中你的数据库你正背着一个很大的风险。 进行更改时,没有一个单一的事实来源,没有回滚位置以及不容易和团队协作。 

8。 编译输出不应加入源代码控制

注意:构建项目自动生成的任何结果不应该提交到源代码控制中。 对于的.NET人们,意味着几乎所有在“bin”和“obj”的文件夹的文件,这通常会是的.dll和.pdb文件。

为什么呢? 因为如果你这样做,你的同事会恨你。 这意味着,每一次他们从版本库更新了变化,则直接用你的覆盖了他们自己的编译输出。 这将是一个合并的噩梦,而且可能打断下次重新编译进程。 然后一旦他们同样这样做重新编译和重新提交,整个该死的问题以相反的方向被重复,这个时候你是在接收端。 

当然,另一个问题是,它只是浪费版本控制机的磁盘,浪费了带宽和额外的延迟,这需要每次到发送它在网络上,并且浪费你每次不可避免的处理冲突的时间。

于是,我们又回到了“忽略”的模式,前面提到的。 只要是“bin”和“obj”路径设置为忽略,一切都变得非常,非常简单。 

事实上,我甚至写了pre-commit钩子在VCS服务器上执行,只要是这样的内容,绝不会到放进源代码控制。 

 

9。 没有人在乎你的个人用户设置

说实话,我觉得很常见地人们甚至不知道他们提交了自己的个人设置到源代码控制。 这里的问题是,许多工具会产生用于管理自己个人的,局部的配置。 这些只适用你,其他人通常会有所不同。 如果你把它们放到VCS,突然间,你都覆盖对方的个人设置。

下面是一个典型的.NET应用程序例子:

Typical .NET app showing user setting files

 

例子是扩展和类型描述情况尚不清楚。ReSharper.user文件和.suo文件都是你的,其他人都没有。

这是原因:让我们来一看,里面ReSharper的文件:

 

 

01.<Configuration>
02.<SettingsComponent>
03.<string />
04.<integer />
05.<boolean>
06.<setting name="SolutionAnalysisEnabled">True</setting>
07.</boolean>
08.</SettingsComponent>
09.<RecentFiles>
10.<RecentFiles>
11.<File id="F985644D-6F99-43AB-93F5-C1569A66B0A7/f:Web.config"
12.caret="1121" fromTop="26" />
13.<File id="F985644D-6F99-43AB-93F5-C1569A66B0A7/f:Site.Master.cs"
14.caret="0" fromTop="0" />

在这个例子中,被记录的事实,我在用户文件中启用方案分析。 对我来说很好,我喜欢它,其他人却不。 通常情况下,因为他们得到的是老龄化,极便宜的PC,但我却不。 问题的关键是,我不应该强迫其他人用我的设置 。

.suo文件同样,里面没有漂亮的XML,该文件记录的东西二进制,如解决方案资源管理器状态,发布设置和其他你不想去强迫其他人的东西。

10。 依赖关系也需要放进源码库

 当一个应用程序需要外部依赖才能成功地构建和运行, 把他们放到源代码控制里。问题是,人们倾向于在自己的小环境用他们自己的设置和本地依赖并使得一切工作好,然后提交一切到源代码控制里,甩手并认为是很酷。 然而,等到任何没有相同本地依赖可用的其他人更新后,一切都灾难性地失败了。

Failing build due to missing NUnit dependencies

我曾参与过一个项目工程假设NUnit在机器上,但这个时候,情况并非如此。 幸运的是伟大的NuGet解放我出来,但事情并不总是那么幸运, 当你开始发现缺少依赖时总是需要一番查找摆弄。 在某些情况下,他们没有公开可用,要试图跟踪这将是是彻头彻尾的痛苦。

我曾碰到这种情况,我从代码库里检出一个项目,去运行它,发现缺少组件位于“C:\ Program Files......”路径。 我花了几小时试图追查谁最后成功运行它,然后组装起来,把它放在项目里一个“库”文件夹中,传到VCS。

当然,如果你工作在任何类型的持续集成环境中,你的构建服务器要安装这些库。 道格·拉思伯恩最近他写了有关源代码控制里的第三方工具 。 

那么大家帮个忙,从第1天开始确保应用程序的构建和运行所需的一切都在VCS。

 

总结

说实话,这些事情都不难,真的都很基本:尽早并频繁提交,知道你正在提交什么,什么应该在VCS里,解释你的提交,并确保你自己亲自提交,不要忘了数据库,别忘记依赖。 但请忘记VSS :)

转载请注明来源 IT瘾 原文 英文

 

 

标签 :

Java应用程序性能调优的原则

这是“ 成为Java GC专家 “系列中的第五篇。 在第一个问题探讨理解Java垃圾收集里,我们已经学会了不同的GC算法的过程,GC如何的工作,新生代和老一代是什么,你应该知道新的JDK 7的5种类型的GC,以及这些GC类型性能的影响有什么。

在第二篇文章-如何监视 Java 垃圾收集中解释了JVM如何实时地运行垃圾收集,我们如何监控GC,和我们可以用来使这个过程更快速,更有效的工具。 

在第三篇文章-如何调整Java的垃圾回收中,我们演示了基于实际例子使用GC调整的最佳选项。 此外,我们解释了如何最大限度地减少传递给老区对象的数量,降低Full GC的时间,以及如何设置GC类型和内存大小。 

在第四篇文章-Apache的MaxClients和Tomcat的全GC 的影响中,我们已经解释了Apache中MaxClients参数的重要性, GC发生时,显着地影响到整个系统的性能。 

在这第五篇文章中,我将解释Java应用程序性能调优的原则。 具体来说,我将解释需要以怎样的顺序调整Java应用程序的性能,确定是否需要调整您的应用程序执行的步骤。 我也解释了性能优化过程中可能遇到的问题。 本文将帮助你做出更好的决策,并给出优化Java应用程序时需要遵循的建议。

 

概述

并不是每一个应用程序都需要调整。 如果应用程序如预期那样执行,您不必施加额外的努力,以提高其性能。 然而,很难期望应用程序能达到完成开发调试时的性能。 这正是需要调优的时候。 无论实现语言是什么,调优应用程序需要很高的专业知识和专心。 此外,您可能不能使用相同的方法像调整某个应用程序一样调整其他应用程序。 这是因为每个应用程序有其独特的操作和不同类型的资源使用情况。 出于这个原因,调整应用程序和编写应用程序所需要的知识相比,需要更多的基本知识。 例如,你需要这些知识:虚拟机,操作系统和计算机体系结构。 当你基于这样的知识专注于应用程序领域,才可以成功地调优应用程序。 

有时Java应用程序优化只需要改变JVM选项,如垃圾收集 ,但有时它需要改变应用程序的源代码。 无论你选择哪种方法,你需要首先监视Java应用程序的执行过程。 出于这个原因,本文将处理的问题如下:

  • 我怎么监视Java应用程序?
  • 我应该做什么样的JVM选项修改?
  • 我怎么能知道,是否需要修改源代码?

 

调整Java应用程序性能所需的知识

Java应用程序运行在Java虚拟机(JVM)。 因此,要优化Java应用程序,你需要了解JVM运行过程。 我曾撰写博客了解JVM内部,那里你可以找到关于JVM的很棒的建议。

这篇文章里提到的关于JVM执行过程的知识主要有GC垃圾回收的知识和Hotspot。 虽然你可能无法用GC或Hotspot知识调整各种Java应用程序性能,但这两个因素在大多数情况下影响着Java应用程序的性能。

值得注意的是,从操作系统的角度看JVM也是一个应用程序进程。 为了能使JVM可以在良好的环境运行,你应该明白OS如何分配资源给进程。 这意味着,调整Java应用程序的性能,你应该有操作系统或硬件以及JVM本身知识。

另一个方面是,Java语言领域的知识也很重要。 同样重要的是要了解锁或并发性和熟悉类加载或创建对象。

当你进行Java应用程序性能调优,你应该运用所有这些方面的知识。

 

Java应用程序性能调优的过程

图1显示了一个流程图,来自由查理·亨特和BinU 约翰共同撰写的书<Java性能>。 这个图表显示了Java应用程序性能调优的过程。

process-tuning-performance-java-applications.png

图1:优化Java应用程序性能流程。 

上述过程不是一个时间过程。 您可能需要重复,直到完成调优。 这也适用于确定一个预期的性能值。 在调整的过程中,有时你应该降低预期的表现值,有时要提高。

 

JVM分配模型

JVM分配模型关系到是否在一个单独的JVM还是在多个JVM上运行Java应用程序。 你可以根据可用性,响应性和可维护性来决定它。 在多台服务器上运行JVM时,您也可以决定是否要在单个服务器上运行多个JVM或每台服务器上运行一个JVM。 例如,对于每个服务器,您可以决定是否执行一个单独使用8 GB堆的JVM,或使用2 GB堆的JVM。 当然,你可以根据CPU内核数量和应用程序的特点,来决定一台服务器上运行的JVM的数量。 在响应方面比较这两个设置时,用2GB比8GB内存可能会更有利应用程序的响应性,使用2 GB的堆进行一次完全的垃圾收集所需时间较短。 但是,如果您使用8 GB堆,可以减少Full GC的频率。 您还可以提高响应速度,增加命中率,如果应用程序使用的内部高速缓存的话。 因此,你可以选择合适的发布模式,考虑应用程序的特点和克服因某些优势而选择模型缺点的方法。

 

JVM体系结构

选择一个JVM是否要使用32位JVM或64位JVM。 在相同的条件下,你最好选择一个32位的JVM。 这是因为一个32位JVM的性能比一个64位的JVM好。 然而,32位JVM的最大逻辑堆的大小是4 GB。 (但是,32位操作系统和64位操作系统实际分配的大小为是2-3 GB)。当需要比这更大的内存时可适当使用64位JVM。

 

Table 1: 性能比较 (source).

Benchmark Time (sec) Factor
C++ Opt 23 1.0x
C++ Dbg 197 8.6x
Java 64-bit 134 5.8x
Java 32-bit 290 12.6x
Java 32-bit GC* 106 4.6x
Java 32-bit SPEC GC* 89 3.7x
Scala 82 3.6x
Scala low-level* 67 2.9x
Scala low-level GC* 58 2.5x
Go 6g 161 7.0x
Go Pro* 126 5.5x
 

下一步是运行应用程序并测量性能。 这个过程包括调整GC,更改操作系统设置和修改代码。 对于这些任务,您可以使用系统监控工具或分析工具。

应当指出,响应速度和吞吐量的调优可以是不同的方法。 如果stop-the-world不时发生,响应能力将会降低,例如,对于一个Full GC的垃圾收集,尽管有大量的每单位时间的吞吐量。 您还需要考虑trade-off可能发生, 在响应速度和吞吐量之间做权衡。 您可能需要使用更多的CPU资源,以减少内存使用量或减少了反应能力或吞吐量。 相反的情况也同样发生,你需要根据优先级处理它。

上面的图1的流程图显示了几乎所有类型的Java应用程序,包括Swing应用程序的性能优化方法。 然而,这张图对编写服务器应用程序的互联网服务有点不适合,像我们公司NHN。 下面的图2中的流程图是一个简单的流程, 在图1的基础上设计的,是更适合NHN。

recommended-procedure-tuning-nhn-java-applications.png

图2:调整NHN的Java应用程序的推荐过程。

在上面的流程图中选择“JVM”是指尽可能使用一个32位的JVM除非你需要使用64位的JVM,以维持几个GB的高速缓存。

现在, 在图2流程图的基础上,你将了解做执行每个步骤要做的事情。

 

JVM选项

我将解释如何指定合适的JVM选项,这主要是针对Web应用程序服务器。 有一种最好的GC算法,尽管没有被应用到每种场景,尤其是Web服务器应用程序,叫并发标记清除GC(Concurrent Mark Sweep GC) 。 这因为最重要的是低延迟 。 当然,在使用Concurrent Mark Sweep GC,有时很长的stop-the-worl现象可能发生。 然而,这个问题是通过调整的新的区域new area的大小或比例可能得到解决。 

指定新的区域new area的大小和指定整个堆大小是一样重要的。 你最好通过使用–XX:NewRatio指定新的区域大小对整个堆大小的比例,或通过使用–XX:NewSize选项,指定所需的新的区域大小。 指定一个新的区域的大小是很重要的,因为大多数的对象不能长期生存。 在Web应用程序中,大多数对象,除了缓存数据,是当HttpResponse到HttpRequest创建时产生的 。 这个时间几乎不超过一秒钟。 这意味着对象的寿命不超过一秒钟。 如果新的区域规模并不大,它应该被转移到老区,以腾出空间给新创建的对象。 GC老区的成本是远远大于新区域的,因此,最好设置新的区域的大小足够。 

如果新区域的大小超过一定的水平,但是响应速度将降低。 这是因为垃圾收集新领域基本上是从一个残留区域的数据复制到另一个残留区。 此时stop-the-world现象会发生,不管是在执行GC新区域还是老区。 如果新的面积变得更大,残留区域的大小将增加,并因此要复制数据的大小也将增加。 鉴于这样的特点,最好通过指定OS HotSpot JVM 的NewRatio设置一个合适的新区域大小 。

 

Table 2: NewRatio by OS and option.

OS and option Default -XX:NewRatio
Sparc -server 2
Sparc -client 8
x86 -server 8
x86 -client 12
 

如果NewRatio被指定 ,整个堆大小的1/(NewRatio +1)就是新区域的大小。 你会发现SPARC -server 的 NewRatio是非常小的。 这是因为SPARC系统通常比x86用于更高端。现在是通常使用x86服务器,其性能也得到提高。 因此,最好是2或3,这个值和 Sparc 服务器类似。

您也可以指定NewSize和MaxNewSize ,而不是NewRatio 。 指定NewSize的值并指定MaxNewSize为最大增量。 根据(指定的或默认值)比例Eden或Survivor残留区域也增加了。 像指定-Xms -Xmx相同大小一样, 最好指定MaxSize和MaxNewSize为相同的大小。

如果您已指定NewRatio和NewSize ,你应该使用较大的一个。 因此,当堆已经创建,您可以表示初始新区域的大小,如下:

min(MaxNewSize, max(NewSize, heap/(NewRatio+1)))

然而,不可能一次测试能确定适当的整个堆大小和新的区域的大小。 根据NHN Web服务器应用程序运行的经验,我建议用下面的JVM选项运行Java应用程序。 使用这些选项监控应用程序的性能后,您可以使用一个更合适的GC算法或选项。

 

Table 3: Recommended JVM options.

Type Option
Operation mode -sever
Entire heap size 指定-Xms和-Xmx为相同的值.
New area size -XX:NewRatio: value of 2 to 4
-XX:NewSize=? –XX:MaxNewSize=?指定NewSize 代替NewRatio也一样.
Perm size -XX:PermSize=256 m -XX:MaxPermSize=256 m指定的值在一定程度上不引起运维问题,因为它不会影响性能.
GC log -Xloggc:$CATALINA_BASE/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStampsGC日志不影响Java应用程序的性能。 建议您尽可能地留下GC日志.
GC algorithm -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75.仅仅是一个大致值得推荐的配置。 其他的选择可能更好,这取决于应用程序的特性.
Creating a heap dump when an OOM error occurs -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_BASE/logs
发生OOM后的操作 -XX:OnOutOfMemoryError=$CATALINA_HOME/bin/stop.sh or -XX:OnOutOfMemoryError=$CATALINA_HOME/bin/restart.sh. 生成 heap dump 后, 根据管理策略采取适当的操作.
 

 

测量应用程序的性能 

要获取的应用程序性能的信息如下:

  • TPS(OPS):了解应用程序性能所需要的信息。
  • 每秒请求(RPS):严格来说,RPS难以感受到,但你可以把它理解为响应能力。 通过RPS,您可以检查用户看到结果所花费的时间。
  • RPS的标准偏差:可能的话有必要达到RPS要求。 如果出现偏差,您需要检查GC调整或互通系统。

 为了获得更准确的性能测试结果,你应该应用程序充分预热后才衡量它。 这是因为预期的HotSpot JIT编译字节代码。 在一般情况下,你可以使用nGrinder负载测试工具进行负载测试某一特征进行至少10分钟后才能得到的实际性能。

 

认真的调整

如果执行nGrinder的结果满足期望,你并不需要调整应用程序的性能。 如果效果没有达到预期,就需要进行调整来解决问题。 下面,您将看到各种案例的处理方法。

 

Stop-the-World事件持续很长

长时间Stop-the-World,可能由于不恰当的GC选项或不正确实施导致。 您可以根据探查器profiler 结果或堆转储heap dump来判定原因。 这意味着你可以检查堆中对象的类型和数量后判断原因。 如果您发现了很多不必要的对象,你最好修改源代码。 如果你发现在创建对象的过程中,没有特别的问题,你只要改变GC的选项来调优。

要适当调整GC的选项,你需要确保有一个足够长时间的GC日志。 您需要了解在什么情况下Stop-the-World需要很长的时间。 选择适当的GC选项的更多信息,请阅读有关如何监视Java垃圾收集博客。

 

阻塞事件时CPU使用率低

当发生阻塞时,TPS和CPU使用率都会下降。 这可能会导致互通系统或并发的问题。 要分析这个问题,你可以使用线程转储thread dump或分析器profiler分析的结果。 线程转储thread dump分析的更多信息,请参阅如何分析Java线程堆

您可以使用商业profiler分析器进行非常精确锁lock分析。 然而,在大多数情况下,你可以用jvisualvm的CPU分析器得到一个满意的结果。

 

CPU使用率高

如果TPS是低的,但CPU的使用率是很高的,这很可能是由于低效率的编码实现导致。 在这种情况下,你应该使用分析器找出瓶颈的位置。 您可以通过使用jvisuavm,Eclipse的TPTPJProbe进行分析。

 

调优方法

建议您使用下面的方法来调整应用程序。

首先,你应该检查是否性能调整是必要的。 性能测量是不容易的工作。 你也不能保证所有的时间都能得到满意的结果。 因此,如果应用程序已经达到其目标性能,你就不必额外投入精力。

问题出在那么少数几个地方,所有您需要做的是解决它。 帕累托原则也适用于性能调整。 这并不意味着低性能的某个功能一定是由一个单一的问题导致的。 相反,在性能调优时我们应该专注于性能影响最大的一个因素。 因此,你应该修复最重要那个问题后接下来处理其他问题。 建议您尝试一次解决一个问题。

你应该考虑气球效应 。 您应该判断什么该放弃什么要抓住。 你可以使用应用缓存提高反应速度,但如果增加高速缓存的大小,进行全面的Full GC所花费的时间也将随之提高。 在一般情况下,如果你想有一个小的内存使用量,吞吐量或响应可能会恶化。 因此,你需要考虑什么是最重要的,什么是不那么重要。

到目前为止,您已经阅读了Java应用程序性能调优的方法。 在介绍具体的性能测量过程中,我不得不省略一些细节。 不过,我认为,这应该满足大多数优化Java Web服务器应用程序的情况。

祝你性能优化成功!

硒勋公园 ,高级软件工程师,网络平台开发实验室,NHN公司。

来源:IT瘾  原文 翻译自:英文

 

标签 : ,