LinFu IoC 高流量网站最佳实践
我们正处于构建一个相当高流量的网站(每周大约 600 万次页面展示)的最后阶段,并使用 LinFu 作为新架构中的 IoC 容器。
我们有一个非常标准的设置:
Web Layer
|
IServices <- Services Implementation
|
IDataRepository <- DataRepository Implementation
|
DataBase
在 Web 层中,我们有一个 LinFu ServiceContainer 实例(我们实现中的单例),它提供页面所需的服务对象实例。 DataRepository 程序集中的每个类也以相同的方式创建(每个 Services 构造函数接受它所需的 DataRepository 对象的接口)。
一个简单的例子是:
IWeatherServices
{
Weather GetForecast();
Weather GetPrediction();
}
[Implements(typeof(IWeatherServices))
WeatherServices(IWeatherForecastRepository, IWeatherPredictionRepository) : IWeatherServices
{
// implementation of methods
}
(DataRepository 类也有类似的功能)
我们目前将生命周期类型保留为默认值(我相信这是 PerRequest)。
我的主要问题是:
- 我们应该将 ServiceContainer 作为 Web 应用程序中的单例吗?
- 实现类上的 LifecycleType 是否应该保留为默认值?
我知道这有点开放,但我们正在负载测试期间进行调整,因此我对一般意见非常感兴趣。
We’re in the final stages of putting together a quite high traffic website (approx 6 million page impressions per week) and are using LinFu as the IoC container within the new architecture.
We have a pretty standard setup:
Web Layer
|
IServices <- Services Implementation
|
IDataRepository <- DataRepository Implementation
|
DataBase
In the web layer, we have an instance of the LinFu ServiceContainer (a singleton in our implementation) that provides instances of Services objects as required by the pages. Each of the classes within the DataRepository assembly is also created in the same way (each Services constructor takes in the interfaces of DataRepository objects that it requires).
A quick example would be:
IWeatherServices
{
Weather GetForecast();
Weather GetPrediction();
}
[Implements(typeof(IWeatherServices))
WeatherServices(IWeatherForecastRepository, IWeatherPredictionRepository) : IWeatherServices
{
// implementation of methods
}
(and similar functionality again for the DataRepository classes)
We’ve left the lifecycle type as the default at the moment (I believe this is PerRequest).
My main questions would be:
- Should we be keeping the ServiceContainer as a singleton within the web app?
- Should the LifecycleType on the implementing classes be kept as the default values?
I know this is a little open-ended but we're in the process of tuning during load testing so am very interested in the general opinion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您不使用 LinFu 的自动字段/属性/方法注入功能,您可以尝试:
这应该会给 LinFu 容器带来显着的性能提升,因为它不必不断检查您的字段、属性和方法以进行自动注入。
If you're not using LinFu's automatic field/property/method injection features, you can try:
That should give the LinFu container a significant performance boost since it won't have to constantly check your fields, properties, and methods for automatic injection.
拥有一个容器实例(即单例)是一件非常常见的事情。但是,请防止在整个应用程序中调用它。相反,使用构造函数注入并让容器仅解析最顶层的对象。从你的例子来看,我相信你已经在这样做了。
短暂的生活方式(在每次调用容器时创建一个新实例)是最简单的事情,而且通常也是最安全的事情。由于多线程而产生竞争条件的变化是最小的。另一方面,这是表现最差的生活方式。
你应该改变生活方式吗?如果你的应用程序足够快,我就不应该打扰。如果速度不够快,您应该了解将服务转移到单身生活方式是否有任何影响。换句话说,请遵循 Rico Mariani 的 10 条绩效规则:衡量、衡量、衡量、衡量,测量,测量,测量,测量,测量,测量:-)
Having one instance of the container (thus a singleton) is a very common thing to do. However, prevent it from being called throughout the application. Instead, use constructor injection and let the container only resolve the top most objects. From looking at your example, I believe you are already doing this.
The transient lifestyle (creating a new instance on each call to the container) is the simplest thing, and often the safest thing to do. The changes of having race conditions because of multi-threading are minimal. On the other hand, it is the worst performing lifestyle.
Should you change the lifestyle? If your application is fast enough, I shouldn't bother. And if it isn't fast enough, you should find out if moving services to a singleton lifestyle has any effect. In other words, follow Rico Mariani's 10 rules for performance: measure, measure, measure, measure, measure, measure, measure, measure, measure, and measure :-)