For a recent edition of the Swiss Computerworld Magazine we listed our Top 10 Performance Problems as we have seen them over the years when working with our clients. I hope this list is enlightening – and I’ve included follow-up links to the blogs to help better understand how to solve these problems:
在最新一期的瑞士电脑杂志中,我们列出了这些年,用我们的客户端所遇到的10 个影响性能的突出问题。我希望这个列表能够给大家启发。同时,为了更好的了解怎样解决这些问题我引入了这些博客的链接。
#1: Too Many Database Calls 调用数据库过多
The problem we see the most are too many database query per request/transaction. There are 3 specific phenomena to witness
More data is requested is than actually required in the context of the current transaction, e.g.: requesting all account information instead of those that we need to display on the current screen.
The same data is requested multiple times. This usually happens when different components involved in the same transaction act independently from one another and each requests the same set of data. It is unknown what type of data has already been loaded in the current context so we end up with the same queries multiple times.
Multiple queries are executed to retrieve a certain set of data. This is often a result of not taken full advantage of complex SQL statements or stored procedures to retrieve the data in one batch.
我们见到的最多的问题是,每次请求或事务,查询数据库的次数太多。这有3种特殊的现象来证实。
在当前事务的上下文中,请求的数据多于实际需要的数据。例如:请求所有用户信息而不是那些我们要显示到当前屏幕的信息。
同样的数据被请求多次。这通常发生在不同的组件在同一个事务中彼此独立的调用,并且每次都请求同类数据。因为不知道哪种类型的数据已经加载到当前的上下文中,最终导致多次相同的查询。
为了取得一特定的数据集执行多次查询操作。这通常是因为没有充分利用复杂 sql语句的优点或存储过程导致的。
Further Reading: Blog on Linq2Sql Performance Issues on Database, Video on Performance Anti-Patterns
#2: Synchronized to Death 同步死锁
There is no question that synchronization is necessary to protect shared data in an application. Too often developers make the mistake to over-synchronize, e.g.: excessively-large code sequences are synchronized. Under low load (on the local developers workstation) performance won’t be a problem. In a high-load or production environment over-synchronization results in severe performance and scalability problems.
毫无疑问,同步在应用中保护共享数据是十分必要的。但有很多开发者犯了过度使用同步的错误。例如:大量的代码序列被同步。低负载(开发者本地的机器上)时性能不会出现问题。在高负载或生产环境中,同步过度使用会导致服务器性能和扩展性问题。
Further Reading: How to identify synchronization problems under load
#3: Too chatty on the remoting channels 与远程通道对话过多
Many libraries out there make remote communication seem like a piece of cake. There is hardly any difference for the developer to call a local vs. remote method. The lack of understanding of what is really going on under the remoting-hood makes people forget about things like latency, serialization, network traffic and memory usage that come with every remoting call. The easy way of using these technologies results in too many calls across these remoting boundaries and in the end causes performance and scalability problems.
很多类库出现使得远程通信看起来小菜一碟。开发者调用本地和远程方法几乎没有什么不同。对远程调用的缺乏了解,使得大家忘了随着每次远程调用产生的诸如延迟、序列化、网络传输和内存消耗等问题。简单的使用这些技术导致这些远程边界穿插太多的调用,最终导致性能和扩展性问题。
Further Reading: Performance Considerations in Distributed Applications
#4: Wrong usage of O/R-Mappers 错误的使用O/R-Mappers
Object-Relational Mappers take a big burden off developers’ shoulders – loading and persisting objects in the database. As with any framework there usually are many configuration options to optimize the usage of the O/R Mapper for current application use cases. Faulty settings and incorrect usage of the framework itself too often results in unexpected performance and scalability problems within these frameworks. Make sure you make yourself familiar with all options and learn about the internals of these libraries that you rely on.
对象关系映射卸下了开发者肩膀上的重担– 加载和在数据库中持久化对象。任何一种框架通常有很多配置选项来优化应用用例的对象关系映射的使用。错误的配置和不正确的使用框架本身过多,导致使用这些框架的不可预料的性能和扩展性问题。确保你自己熟悉所有的配置项并且了解你所依靠的类库的内部。
Further Reads: Understanding Hibernate Session Cache, Understanding the Query Cache, Understanding the Second Level Cache
#5: Memory Leaks 内存泄漏
Managed runtime environments such as Java and .NET have the advantage of helping with memory management by offering Garbage Collectors. A GC, however, does not prevent memory leaks. Objects that are “forgotten” will stick around in memory and ultimately lead to a memory leak that may cause an OutOfMemoryException. It is important to release object references as soon as they are no longer needed.
运行时环境的管理,像Java和.NET都有垃圾回收器帮助进行内存管理。但是,垃圾回收器却不能阻止内存泄漏。被遗忘的对象会驻留在内存中,最终导致内存泄漏出现OutOfMemoryException。及时的释放掉对不再需要的对象的引用很重要。
Further Read: Understanding and finding Memory Leaks
#6: Problematic 3rd Party Code/Components 第三方代码或组件的问题
Nobody is writing all of the functionality of a new application on their own. We use existing 3rd party libraries to speed up our development process. Not only do we speed up our output – but we also increase performance risks introduced by these components. Even though most frameworks are well documented and have been thoroughly tested, there is no guarantee that these frameworks run as expected in every use case they are included. 3rd party code is often used incorrectly or in ways that have not been tested. It is therefore important to make an in-depth check of every framework before introducing it into your code.
没有人靠自己写一个新应用的所有功能。我们使用第三方的类库来加快我们的开发进度。我们在加快我们输出的同时,也增加了由这些组件带来的性能风险。尽管多数的框架有很好的文档且经过十分彻底的测试,但不能保证这些框架适用于所有情况。他们经常被不正确的使用,或不经过测试就使用。所有,在引入你的代码之前,要对所有这些框架进行深入的检查。
Further Read: Top SharePoint Performance Mistakes
#7: Wasteful handling of scarce resources 稀少资源的浪费使用
Resources such as memory, CPU, I/O or the database are scarce. Wasteful handling of these resources results in lack of access to these resources by others and ultimately leads to performance and scalability issues. A good example: database connections that are kept open for too long. Connections must only be used for the time period they are really needed, e.g.: for a query – and then returned to the connection pool. We often see that connections are requested early on in the request handler and are not released until the very end which leads to a classic bottleneck situation.
像内存、CPU、I/O或数据库这类资源都是稀少的。对这些资源的浪费使用导致其他人不能调用这些资源,最终导致性能和扩张性问题。举个例子:数据库连接时间太长。连接应该只有在真正需要的期间段使用。例如,查询时连接,然后把连接归还给连接池。我们经常看到在处理请求很早之前就请求连接,并且直到最后也没有释放连接,这就导致瓶颈现象的出现。
Further Read: Resource Leak detection in .NET Applications
#8: Bloated web frontends 臃肿的WEB前端
Thanks to high-speed web access many users have a better end-user experience in the World Wide Web. The downside of this trend is that many applications get packed with too much stuff – they become bloated – which ultimately leads to bad browsing behavior. Particularly users that do not yet have high-speed internet access suffer the most. Too many images that are too large; failure to use or incorrect usage of the browser cache; or overly-aggressive usage of JavaScript/AJAX – all result in performance problems in the browser. Following the existing Best Practices on Web Site Performance Optimization can solve most of these problems.
由于网络的高速接入,用户有了更好的用户体验。不好的趋势是很多应用打包的东西太多,他们变得臃肿,最终导致浏览器出现错误。那些还没有高速网络接入的用户会遇到这样的问题会最多。图片过大过多,错误的使用浏览器的缓存,过度的使用JavaScript或Ajax,所有这些都会导致浏览器的性能问题。按照已有网站的成功案例来优化能解决这些问题。
Further Reads: How Better Caching would help speed up Frankfurt Airport Web Site, Best Practices on Web Performance Optimization
#9: Wrong Cache Strategy leads to excessive Garbage Collection 错误的缓存策略导致垃圾回收过度
Caching objects in memory to avoid constant roundtrips to the database is one way to boost performance. Caching too many objects – or objects that are hardly ever used quickly changes the advantage of caching into a disadvantage due to higher memory usage and increased GC activity. Before implementing a caching strategy you have to figure out which objects to cache and which objects not to cache in order to avoid these types of performance and scalability problems.
把对象在内存中缓存,来避免持续的对数据库的反复调用是提升性能的一种方法。缓存太多的对象,或者缓存的对象不是经常使用,会把缓存的优点变成缺点,因为消耗的内存过多并且增加了GC的活动。在实现一个缓存策略之前,有应该知道那些对象应该缓存,哪些对象不应该缓存来避免这些性能和扩展性问题。
Further Reads: Java Memory Problems, Identify GC Bottlenecks in Distributed Applications
#10: Intermittent Problems 间歇性问题
Intermittent problems are hard to find. These are usually problems that occur with specific input parameters or only happen under certain load conditions. Full test coverage – functional as well as load and performance coverage – will uncover most of these problems early on before they become real problems for real users.
间歇性问题很难被发现。这些问题在输入特殊参数或一定负载时才会经常出现。测试覆盖要全面,功能测试、负载测试和性能测试都要覆盖到。这样才能在成为最用用户遇到的问题之前发现这些问题。
Further Reads: Tracing Intermittent Errors by Lucy Monahan from Novell, How to find invisible performance problems
(Bonus Problem) #11: Expensive Serialization (附加问题)昂贵的序列化
With remoting communication – such as Web Services, RMI or WCF – objects need to serialized by the caller in order to be transferred over the network. The callee on the other side needs to de-serialize the object before it can be used. Transformation therefore happens on both sides of the call resulting in some overhead while doing so. It is important to understand what type of serialization is required by both ends and what the optimal choice of serialization and transport type is. Different types of serialization have a different impact on performance, scalability, memory usage and network traffic.
使用远程通信,像Web Service,RMI 或 WCF。对象需要被调用者序列化来在网络中传输。网络另一端的被调用者需要在使用这个对象前反序列化。传输时两端都这样做的话会导致一些资源消耗。知道两端需要什么类型的序列化,哪种序列化和传输类型是最优的很重要。不同类型的序列化对性能、扩展性、内存使用和网络传输会产生不同的影响。
Further Read: Performance Considerations in Distributed Applications
本文摘自:http://blog.dynatrace.com/2010/06/15/top-10-performance-problems-taken-from-zappos-monster-and-co/
在最新一期的瑞士电脑杂志中,我们列出了这些年,用我们的客户端所遇到的10 个影响性能的突出问题。我希望这个列表能够给大家启发。同时,为了更好的了解怎样解决这些问题我引入了这些博客的链接。
#1: Too Many Database Calls 调用数据库过多
The problem we see the most are too many database query per request/transaction. There are 3 specific phenomena to witness
More data is requested is than actually required in the context of the current transaction, e.g.: requesting all account information instead of those that we need to display on the current screen.
The same data is requested multiple times. This usually happens when different components involved in the same transaction act independently from one another and each requests the same set of data. It is unknown what type of data has already been loaded in the current context so we end up with the same queries multiple times.
Multiple queries are executed to retrieve a certain set of data. This is often a result of not taken full advantage of complex SQL statements or stored procedures to retrieve the data in one batch.
我们见到的最多的问题是,每次请求或事务,查询数据库的次数太多。这有3种特殊的现象来证实。
在当前事务的上下文中,请求的数据多于实际需要的数据。例如:请求所有用户信息而不是那些我们要显示到当前屏幕的信息。
同样的数据被请求多次。这通常发生在不同的组件在同一个事务中彼此独立的调用,并且每次都请求同类数据。因为不知道哪种类型的数据已经加载到当前的上下文中,最终导致多次相同的查询。
为了取得一特定的数据集执行多次查询操作。这通常是因为没有充分利用复杂 sql语句的优点或存储过程导致的。
Further Reading: Blog on Linq2Sql Performance Issues on Database, Video on Performance Anti-Patterns
#2: Synchronized to Death 同步死锁
There is no question that synchronization is necessary to protect shared data in an application. Too often developers make the mistake to over-synchronize, e.g.: excessively-large code sequences are synchronized. Under low load (on the local developers workstation) performance won’t be a problem. In a high-load or production environment over-synchronization results in severe performance and scalability problems.
毫无疑问,同步在应用中保护共享数据是十分必要的。但有很多开发者犯了过度使用同步的错误。例如:大量的代码序列被同步。低负载(开发者本地的机器上)时性能不会出现问题。在高负载或生产环境中,同步过度使用会导致服务器性能和扩展性问题。
Further Reading: How to identify synchronization problems under load
#3: Too chatty on the remoting channels 与远程通道对话过多
Many libraries out there make remote communication seem like a piece of cake. There is hardly any difference for the developer to call a local vs. remote method. The lack of understanding of what is really going on under the remoting-hood makes people forget about things like latency, serialization, network traffic and memory usage that come with every remoting call. The easy way of using these technologies results in too many calls across these remoting boundaries and in the end causes performance and scalability problems.
很多类库出现使得远程通信看起来小菜一碟。开发者调用本地和远程方法几乎没有什么不同。对远程调用的缺乏了解,使得大家忘了随着每次远程调用产生的诸如延迟、序列化、网络传输和内存消耗等问题。简单的使用这些技术导致这些远程边界穿插太多的调用,最终导致性能和扩展性问题。
Further Reading: Performance Considerations in Distributed Applications
#4: Wrong usage of O/R-Mappers 错误的使用O/R-Mappers
Object-Relational Mappers take a big burden off developers’ shoulders – loading and persisting objects in the database. As with any framework there usually are many configuration options to optimize the usage of the O/R Mapper for current application use cases. Faulty settings and incorrect usage of the framework itself too often results in unexpected performance and scalability problems within these frameworks. Make sure you make yourself familiar with all options and learn about the internals of these libraries that you rely on.
对象关系映射卸下了开发者肩膀上的重担– 加载和在数据库中持久化对象。任何一种框架通常有很多配置选项来优化应用用例的对象关系映射的使用。错误的配置和不正确的使用框架本身过多,导致使用这些框架的不可预料的性能和扩展性问题。确保你自己熟悉所有的配置项并且了解你所依靠的类库的内部。
Further Reads: Understanding Hibernate Session Cache, Understanding the Query Cache, Understanding the Second Level Cache
#5: Memory Leaks 内存泄漏
Managed runtime environments such as Java and .NET have the advantage of helping with memory management by offering Garbage Collectors. A GC, however, does not prevent memory leaks. Objects that are “forgotten” will stick around in memory and ultimately lead to a memory leak that may cause an OutOfMemoryException. It is important to release object references as soon as they are no longer needed.
运行时环境的管理,像Java和.NET都有垃圾回收器帮助进行内存管理。但是,垃圾回收器却不能阻止内存泄漏。被遗忘的对象会驻留在内存中,最终导致内存泄漏出现OutOfMemoryException。及时的释放掉对不再需要的对象的引用很重要。
Further Read: Understanding and finding Memory Leaks
#6: Problematic 3rd Party Code/Components 第三方代码或组件的问题
Nobody is writing all of the functionality of a new application on their own. We use existing 3rd party libraries to speed up our development process. Not only do we speed up our output – but we also increase performance risks introduced by these components. Even though most frameworks are well documented and have been thoroughly tested, there is no guarantee that these frameworks run as expected in every use case they are included. 3rd party code is often used incorrectly or in ways that have not been tested. It is therefore important to make an in-depth check of every framework before introducing it into your code.
没有人靠自己写一个新应用的所有功能。我们使用第三方的类库来加快我们的开发进度。我们在加快我们输出的同时,也增加了由这些组件带来的性能风险。尽管多数的框架有很好的文档且经过十分彻底的测试,但不能保证这些框架适用于所有情况。他们经常被不正确的使用,或不经过测试就使用。所有,在引入你的代码之前,要对所有这些框架进行深入的检查。
Further Read: Top SharePoint Performance Mistakes
#7: Wasteful handling of scarce resources 稀少资源的浪费使用
Resources such as memory, CPU, I/O or the database are scarce. Wasteful handling of these resources results in lack of access to these resources by others and ultimately leads to performance and scalability issues. A good example: database connections that are kept open for too long. Connections must only be used for the time period they are really needed, e.g.: for a query – and then returned to the connection pool. We often see that connections are requested early on in the request handler and are not released until the very end which leads to a classic bottleneck situation.
像内存、CPU、I/O或数据库这类资源都是稀少的。对这些资源的浪费使用导致其他人不能调用这些资源,最终导致性能和扩张性问题。举个例子:数据库连接时间太长。连接应该只有在真正需要的期间段使用。例如,查询时连接,然后把连接归还给连接池。我们经常看到在处理请求很早之前就请求连接,并且直到最后也没有释放连接,这就导致瓶颈现象的出现。
Further Read: Resource Leak detection in .NET Applications
#8: Bloated web frontends 臃肿的WEB前端
Thanks to high-speed web access many users have a better end-user experience in the World Wide Web. The downside of this trend is that many applications get packed with too much stuff – they become bloated – which ultimately leads to bad browsing behavior. Particularly users that do not yet have high-speed internet access suffer the most. Too many images that are too large; failure to use or incorrect usage of the browser cache; or overly-aggressive usage of JavaScript/AJAX – all result in performance problems in the browser. Following the existing Best Practices on Web Site Performance Optimization can solve most of these problems.
由于网络的高速接入,用户有了更好的用户体验。不好的趋势是很多应用打包的东西太多,他们变得臃肿,最终导致浏览器出现错误。那些还没有高速网络接入的用户会遇到这样的问题会最多。图片过大过多,错误的使用浏览器的缓存,过度的使用JavaScript或Ajax,所有这些都会导致浏览器的性能问题。按照已有网站的成功案例来优化能解决这些问题。
Further Reads: How Better Caching would help speed up Frankfurt Airport Web Site, Best Practices on Web Performance Optimization
#9: Wrong Cache Strategy leads to excessive Garbage Collection 错误的缓存策略导致垃圾回收过度
Caching objects in memory to avoid constant roundtrips to the database is one way to boost performance. Caching too many objects – or objects that are hardly ever used quickly changes the advantage of caching into a disadvantage due to higher memory usage and increased GC activity. Before implementing a caching strategy you have to figure out which objects to cache and which objects not to cache in order to avoid these types of performance and scalability problems.
把对象在内存中缓存,来避免持续的对数据库的反复调用是提升性能的一种方法。缓存太多的对象,或者缓存的对象不是经常使用,会把缓存的优点变成缺点,因为消耗的内存过多并且增加了GC的活动。在实现一个缓存策略之前,有应该知道那些对象应该缓存,哪些对象不应该缓存来避免这些性能和扩展性问题。
Further Reads: Java Memory Problems, Identify GC Bottlenecks in Distributed Applications
#10: Intermittent Problems 间歇性问题
Intermittent problems are hard to find. These are usually problems that occur with specific input parameters or only happen under certain load conditions. Full test coverage – functional as well as load and performance coverage – will uncover most of these problems early on before they become real problems for real users.
间歇性问题很难被发现。这些问题在输入特殊参数或一定负载时才会经常出现。测试覆盖要全面,功能测试、负载测试和性能测试都要覆盖到。这样才能在成为最用用户遇到的问题之前发现这些问题。
Further Reads: Tracing Intermittent Errors by Lucy Monahan from Novell, How to find invisible performance problems
(Bonus Problem) #11: Expensive Serialization (附加问题)昂贵的序列化
With remoting communication – such as Web Services, RMI or WCF – objects need to serialized by the caller in order to be transferred over the network. The callee on the other side needs to de-serialize the object before it can be used. Transformation therefore happens on both sides of the call resulting in some overhead while doing so. It is important to understand what type of serialization is required by both ends and what the optimal choice of serialization and transport type is. Different types of serialization have a different impact on performance, scalability, memory usage and network traffic.
使用远程通信,像Web Service,RMI 或 WCF。对象需要被调用者序列化来在网络中传输。网络另一端的被调用者需要在使用这个对象前反序列化。传输时两端都这样做的话会导致一些资源消耗。知道两端需要什么类型的序列化,哪种序列化和传输类型是最优的很重要。不同类型的序列化对性能、扩展性、内存使用和网络传输会产生不同的影响。
Further Read: Performance Considerations in Distributed Applications
本文摘自:http://blog.dynatrace.com/2010/06/15/top-10-performance-problems-taken-from-zappos-monster-and-co/
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:http://jackxiang.com/post/3494/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
评论列表