我爱我老婆

用HttpWebRequest去Call别的Service,怎样才能提高并发量和性能?

 

因为建立一个TCP连接要三次握手,.Net 默认使用 keepAlive = Ture 去重用连接,避免重建Connection的开销,还有一些设置我们也要注意:

 

DefaultConnectionLimit


  description: Maximum number of concurrent connections to a single ServicePoint


  default: 2


  suggested: 12*N, N is the number of CPU
  
MaxServicePointIdleTime


  description: Maximum idle time of ServicePoint object, but in the testing, i found it's the maximum idle time of the TCP connection in connection pool, http://msdn.microsoft.com/en-US/library/system.net.servicepointmanager.maxservicepointidletime.aspx


  default: 100000ms


  suggested: 3600000ms, 1 hour, set a long time to keep the connection, avoid creating connection every call.
  

ConnectionLeaseTimeout


  description: A Int32 that specifies the number of milliseconds that an active ServicePoint connection remains open. The default is -1, which allows an active ServicePoint connection to stay connected indefinitely. Set this property to 0 to force ServicePoint connections to close after servicing a request.


  default: -1


  suggested: -1


MaxServicePoints


  description: Maximum number of concurrent ServicePoint objects


  default: 0, means no limited.


  suggested: 0

 

TcpKeepAliveTimeInMillis 


  description: after idle more than n ms, a keepalive tcp package will be send by client, to verify the connection is still available or not.


  default: 7200000ms, 2 hours


  suggested: 10000ms, 10s, recyle the bad connections in time, reduce the burden of the server.

 

TcpKeepAliveIntervalInMillis


  description: between when successive keep-alive packets are sent if no acknowledgement is received, until received a response, if 5 packages were sent, and no any response, this connection will be drop, http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.settcpkeepalive.aspx


  default: 1000ms


  suggested: 1000ms

 

ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = false;

 

MaxWorkerThreads    100
MaxIOThreads     100
MaxConnection     12*N
MinfreeThreads     88*N
MinLocalRequestfreeThreads   88*N
MinWorkerThreds     50  (MaxWorkerThreads/2)

 

参考资料:

http://support.microsoft.com/kb/821268
http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83
http://blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx
http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx

 

posted @ 2012-02-01 15:23 DataFlow 阅读(7) 评论(0) 编辑

既然有了xs:integer,为什么还要有xs:int?

经过一番查找,真相浮出:

 

xs:integer 无小数的任意长度的整数, 如果要表示money, 或者会很大的数字,或者需要方便以后的扩展,这个会更合适

xs:int        无小数的32位长度的整数

 

经过xsdGencode或者svcutil生成之后,
 
使用xs:integer标识的属性将转为C#中的string类型
使用xs:int标识的属性将转为int类型
 
可能int类型会在性能上比string好些,于是有了下面的测试:
 
1. 定义一个xsd, 分别使用30个xs:int/ xs:integer, 再转成DataContract
2. 分别运行反序列化100W次
3. 差别在700ms, 所以每次运行的差别在0.0007ms, 所以意义不大,而且还有逻辑中类型转换的开销。
 
结论,一般在定义xsd时,使用xs:integer为上.
 
 
posted @ 2012-01-29 10:18 DataFlow 阅读(4) 评论(0) 编辑

以下实现的目标是:

localhost:6677/Services/China

localhost:6677/Services/USA

localhost:6677/Services/...

 

以上所有调用都走到Service方法中,因为支持的国家是未知的,不能写成方法,并且请求的schame已经确定,不能再做修改,所以就有了以下实现:

 

定义Service Interface,包含一个方法Service.

 

代码 比较简单,只是重写OperationSelector属性,返回所有请求到方法"Service"(大小区分)

 

 

public class RouteBehaviorExtension : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(RouteBehavior); }
}
protected override object CreateBehavior()
{
return new RouteBehavior();
}
}

public class RouteBehavior : Attribute, IEndpointBehavior
{
private _operationSelector;

public RouteBehavior()
{
_operationSelector = new Router();
}

public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.OperationSelector = _operationSelector;
}

public void Validate(ServiceEndpoint endpoint)
{
}
}

internal class Router : IDispatchOperationSelector
{
public string SelectOperation(ref Message message)
{
return "Service";
}
}

 

配置:

添加RouteBehaviorExtension,并加该Behavior到EndpointBehaviors(注意Behavior的顺序,从上而下依次执行的)

 

取第二个参数:

OperationContext.Current.IncomingMessageHeaders.To.Segments[2]

posted @ 2011-12-31 16:52 DataFlow 阅读(10) 评论(0) 编辑

在windows services开发中,碰到一个奇怪的问题:

 

有时可以启动,有时启动超时,经过漫长的分析(有引用其它的组件),发现问题出在Performance counter的创建上,sometimes, the code will be hang here.

 

Link:

http://www.pcreview.co.uk/forums/strange-performance-counter-performance-problem-windows-service-application-t2781664.html

 

解决方法:

 

将Performance Counter操作放到OnStart方法中,不要放到ServiceBase.Run之前就可以.

.Net 的Bug也真是不少啊

posted @ 2011-12-03 01:06 DataFlow 阅读(4) 评论(0) 编辑
private void InternalWriteEvent(uint eventID, ushort category, EventLogEntryType type, string[] strings, byte[] rawData, string currentMachineName);
Declaring Type:System.Diagnostics.EventLogInternal
Assembly:System, Version=4.0.0.0
private void InternalWriteEvent(uint eventID, ushort category, EventLogEntryType type, string[] strings, byte[] rawData, string currentMachineName)
{
    if (strings == null) strings = new string[0];
    if (strings.Length >= 0x100) throw new ArgumentException(SR.GetString("TooManyReplacementStrings"));
    for (int i = 0; i < strings.Length; i++)
    {
        if (strings[i] == null) strings[i] = string.Empty;
        if (strings[i].Length > 0x7ffe) throw new ArgumentException(SR.GetString("LogEntryTooLong"));
    }
    if (rawData == null) rawData = new byte[0];
    if (this.Source.Length == 0) throw new ArgumentException(SR.GetString("NeedSourceToWrite"));
    if (!this.IsOpenForWrite) this.OpenForWrite(currentMachineName);
    IntPtr[] ptrArray = new IntPtr[strings.Length];
    GCHandle[] handleArray = new GCHandle[strings.Length];
    GCHandle handle = GCHandle.Alloc(ptrArray, GCHandleType.Pinned);
    try
    {
        for (int j = 0; j < strings.Length; j++)
        {
            handleArray[j] = GCHandle.Alloc(strings[j], GCHandleType.Pinned);
            ptrArray[j] = handleArray[j].AddrOfPinnedObject();
        }
        byte[] userSID = null;
        if (!UnsafeNativeMethods.ReportEvent(this.writeHandle, (short) type, category, eventID, userSID, (short) strings.Length, rawData.Length, new HandleRef(this, handle.AddrOfPinnedObject()), rawData)) throw SharedUtils.CreateSafeWin32Exception();
    }
    finally
    {
        for (int k = 0; k < strings.Length; k++)
        {
            if (handleArray[k].IsAllocated) handleArray[k].Free();
        }
        handle.Free();
    }
}
如果不喜欢GC的自动垃圾回收,可以试试这种方式,说不定效果更好.
 
posted @ 2011-12-02 16:22 DataFlow 阅读(3) 评论(0) 编辑
摘要: 有些开发人员喜欢在代码中写大量的注释,认为这样可以增加代码的可读性,而很多大牛却也很少写,之前也是不解。大量的注释的确可以帮助读代码的人,更快得理解,但往往增加了我们的关注点,代码看起来也不漂亮,Jobs告诉了我,什么才是最美? 是简约之美...又想增加代码的可读性,又想减少甚至不用注释,这是个矛盾嘛,像是一道永远无解的数字游戏,最近有些感悟,找到了答案:思想:类名,方法名,属性名,变量名,即是注释,无处不是注释,无论一个业务多复杂的系统,只要设计合理了,处处井井有条了,即使没有一行注释,代码读起来也是很清晰,漂亮。方法论:当你有冲动要加点注释的时候,先问下自己,要描述的逻辑是否可以封装成方法阅读全文
posted @ 2011-11-30 10:04 DataFlow 阅读(8) 评论(0) 编辑
摘要: 通常会有些用户名,密码被配置在web.config文件中,而且是明文,这就增加了站点的风险。解决方案有:aspnet_regiis.exe -pe passwordSection/LogDB -app /[applicationname]passwordSection/LogDB 为xmlpath.部署后,配置文件里是加密的,读的时候,却是正常读,asp.net会帮你解决一切,好和谐.但是,这里面有个Bug, 如果passwordSection的解析类是你自定义的,那么你会很不幸,因为加密会失败。只有解析类是FCL中的类才会成功。解决方案是,自定义一个Section, like:<sec阅读全文
posted @ 2011-11-28 11:17 DataFlow 阅读(7) 评论(0) 编辑
摘要: User cache to hold connectionhttp://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspxno sleep of ThreadPoolhttp://blogs.msdn.com/b/wenlong/archive/2010/02/11/why-does-wcf-become-slow-after-being-idle-for-15-seconds.aspxhttp://msd阅读全文
posted @ 2011-11-17 11:39 DataFlow 阅读(1) 评论(0) 编辑
摘要: http://blogs.msdn.com/b/webtopics/archive/2009/02/13/asp-net-hang-in-iis-7-0.aspxhttp://blogs.msdn.com/b/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx阅读全文
posted @ 2011-09-04 11:16 DataFlow 阅读(11) 评论(0) 编辑
摘要: 1. 自动格式化输出的XML: <xsl:strip-space elements="*"/>2. match 所有存在i:nil属性的节点: <xsl:template match="@*|node()[@i:nil]"</xsl:template>3. 在所有节点中查找: <xsl:temp[late match="@*|node()">4. 过滤所有以'hello'结尾的节点:<xsl:if test="substring(name(),string-le阅读全文
posted @ 2011-08-15 10:23 DataFlow 阅读(6) 评论(0) 编辑