蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 596, 评论 - 4064, 引用 - 276

导航

关于

这里是我的技术Blog,下一代CSDN社区Blog在 http://blog.csdn.net/ghj1976/

标签

每月存档

最新留言

  • re:学习笔记:7种结构型设计模式简单对比
    <p>最新在家创业系统 ----刚从国外引进,市场巨大。 ----在家可经营所有国家生意,事业规模宏大。 ----不需求人与说服;不用放厚脸皮去推销。 ----极小投资;零风险;成...
    by jackielongteng(注册) on 2009/6/14 13:43:56
  • re:作用域
    <p>☆                    &deg;∵☆       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
    by jackielongteng(注册) on 2009/6/14 13:03:25
  • re:Html标签嵌套对展示性能的影响
    <p><strong>所有的浏览器都按照你提到的浏览器解析Html规则来解析嘛?</strong></p>
    by Cola(注册) on 2009/6/12 23:07:28
  • re:Html5
    <p>目前来说,HTML5还只是一个梦想,呵呵:)</p>
    by 开心就好(注册) on 2009/6/11 16:31:54
  • re:多线程与SqlConnection.Close
    <p>好服月租型IT服务台,与你共成长! 月租型ITSM软件,注册即可免费体验! 详情请登录官方网站:<a href="http://www.servicezon.co...
    by qzhibo(注册) on 2009/6/3 15:14:21
  • re:多线程Singleton单件模式
    <pre><span style="color: #0000ff;">//Another way public</span> <sp...
    by Yaojian(注册) on 2009/4/22 14:02:35
  • re:Thread.Sleep(0)
    <p>学习了~</p>
    by shuitong888(注册) on 2009/4/8 14:29:24
  • re:Html标签嵌套对展示性能的影响
    <p>DIV固然好 但IE6,7,8 firefox,safari ....做美工的人要累死.</p>
    by ryq1(注册) on 2009/4/3 14:16:25
  • re:用.net 编码实现朗读文本的方法
    <p>我第一次 按键时 能听到声音,但是第二次按键时,没反应。网页一直在 loading.&nbsp;是什么原因?</p>
    by tracytang949(注册) on 2009/3/27 7:01:09
  • re:information_schema.routines与sysobjects
    <p>用sys.procedures多好。</p>
    by luke(注册) on 2009/3/16 16:45:49
  • re:SQL Server 2005 配置发送邮件
    <p>&lt;A href="<a href="http://www.3rt.info">http://www.3rt.info</...
    by ives007(注册) on 2009/2/26 16:47:00
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:45:08
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:32:06
  • re:虚机搭配NLB负载平衡时碰到"没有接口可用于安装新的群集"的解决方案
    <p>google newsid</p>
    by iads(注册) on 2009/2/13 17:25:07
  • re:try catch 与线程
    <p>确实是这样的。因为异常机制本质上是堆栈操作,而各线程的堆栈是独立的。</p>
    by st_szr(注册) on 2009/1/21 9:46:05
  • re:try catch 与线程
    <p>没啥啊,线程就是新启动了一个,当然异常不会影响到原有的线程了。</p> <p>你应该在线程里面合适的位置写上自己的捕获代码就行了。</p>
    by laozizhu(注册) on 2009/1/19 16:33:21
  • re:我的2008,征服天堂
    <p>蝈蝈,可惜我帮不了你啊!</p>
    by laozizhu(注册) on 2009/1/19 16:25:45
  • re:try catch 与线程
    <p>呃&hellip;&hellip;是这样的。可怎么处理呢?</p>
    by Anders Liu(注册) on 2009/1/19 11:58:05
  • re:我的2008,征服天堂
    <p>博主是不是去了师部 做了侦查营长呢?</p>
    by huobazi(注册) on 2009/1/9 14:15:33
  • re:我的2008,征服天堂
    <p>@ghj1976:看来真的危机了</p>
    by 开心就好(注册) on 2009/1/9 10:17:37
  • re: 网络带宽的单位
    不过传输的时候,往往还有压缩。
    by luke(匿名) on 2008/12/15 11:00:21
  • re: 网络带宽的单位
    除10不仅仅是为了方便,在传输中,往往加上控制位,所以一个字节往往需要10Bit.
    by 关门放狗(匿名) on 2008/12/13 16:01:30
  • re: 多缓存并存
    对跨进程甚至跨服务器缓存的性能比较怀疑,进程通信和跨服务器通信代价不菲。即使有已有进程外数据可用,如果考虑在进程做份缓存,定期再进程间同步是否更佳?
    by jinglecat(匿名) on 2008/12/12 18:00:05
  • re: 网络带宽的单位
    好像还有一个为了方便换算,厂家使用的是 除10的处理方式的说法:于是100Mb/sec = 100M / 10 = 10M Byte/sec 所以我通常都是用除10而不是除8来做运算的。
    by kentliu(匿名) on 2008/12/11 11:38:55
  • re: 网络带宽的单位
    又不是大S小s
    by luke(匿名) on 2008/12/10 12:04:50

广告

【第1页/共24页,596条】
首页
前页
1
...
2009年06月23日

今天很怪异,我的PowerPoint出现了下面的提示对话框后,不论我选择是或者否,我的PowerPoint都再也打不开了。

未命名

网上搜索了相关资料,通过下面步骤删除这个插件后,就可以正常使用了。

  • 单击开始→运行→输入Powerpnt.exe /safe回车,尝试以安全模式运行POWERPOINT。
  • 如果可以运行,点击POWERPOINT选项→加载项→里面的活动应用程序加载项→去除对应插件。

 

参考资料:

启用或禁用 Office 程序中的加载项
http://office.microsoft.com/zh-cn/help/HA100341272052.aspx

http://bbs.kafan.cn/thread-459528-2-9.html

posted on 2009-06-23 16:58:45 by ghj1976  评论(0) 阅读(1430)

 
2009年06月17日

     硅脂对CPU的热量向散热风扇的传递很重要,上周对我家电脑的处理对此深有感受。特写此篇Blog。

     之前我家的台式机由于频繁出现无法启动。症状是:主板灯亮,风扇都在转,但是就是无法启动,而且主板没有任何嘟嘟提醒。每次碰到这种情况,我需要把CPU拆下来,重新装上去才可以启动。我怀疑就是CPU热量散不出去的原因,在能启动的时候,通过进入主板的管理界面,看到一开机,CPU的温度就是74度。风扇乌鸦乌鸦的响。

     后来就是买了硅脂,涂在风扇跟CPU接触面上后,开机进入BIOS 后,发现CPU温度只有三十多度,玩一个3D的游戏时,也只有60度。之前不能启动的问题也就解决了。由于我家电脑的风扇是可以根据温度变转速的,之前开机后风扇很响的问题也解决了。  

参考:

实践出真知-4种硅脂涂法详尽测试
http://mb.beareyes.com.cn/2/lib/200801/24/20080124504.htm

posted on 2009-06-17 10:18:10 by ghj1976  评论(0) 阅读(2011)

 
2009年06月12日

昨天花了2个小时调试有时候启动了定时轮询,有时候没有启用定时轮询的bug,最后发现竟然是作用域的问题,比较汗颜,下面就是有bug的这个代码的简单写法:

using System;
using System.Timers;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        Begin();
        Console.ReadLine();
    }


    public static void Begin()
    {
        TimerCallback callbackMethod = new TimerCallback(Program.Check);
        int pollCycleInMilliseconds = 180000;
        System.Threading.Timer pollTimer = new System.Threading.Timer(
            callbackMethod, null, pollCycleInMilliseconds, pollCycleInMilliseconds);

    }

    public static void Check(object notUsed)
    {
        Console.Write(DateTime.Now);
    }
}

出bug是因为这里的 System.Threading.Timer pollTimer 是一个局部变量,这个变量出了他的作用域,可能会被销毁以及垃圾回收,这时候,自然就没有了定时轮询的触发了。

实际的代码比这里要复杂很多,是个WEB应用。一直没想到是作用域的问题才导致花了这么长时间找bug。把这个我碰到的bug记录下来,让碰到类似问题的人也好有思路提醒。

posted on 2009-06-12 09:31:15 by ghj1976  评论(1) 阅读(2288)

 
2009年06月08日

这7种结构型设计模式是下面7种:

  • Adapter 适配器模式
  • Bridge 桥接模式
  • Composite 组合模式
  • Decorator 装饰模式
  • Facade 外观模式
  • Flyweight 享元模式
  • Proxy 代理模式

对比:

  • Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况” ,在遗留代码复用、类库迁移等方面非常有用。
  • Bridge模式的应用一般在“两个非常强的变化维度”。Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维护来变化。
  • Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。 将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口(而非对象容器的复杂内部实现)发生依赖关系,从而更能“应对变化”。
  • 通过采用组合、而非继承的手法, Decorator(装饰)模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。
  • 从客户程序的角度来看, Facade(外观)模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Façade接口的变化。Façade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Façade很多时候更是一种架构设计模式。
  • 面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight(享元)设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。 运用共享技术有效地支持大量细粒度的对象。
  • Proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。

从接口的角度来看:

  • Adapter模式注重转换接口; 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
  • Bridge模式注重分离接口(抽象)与其实现; 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
  • Decorator(装饰)模式注重稳定接口的前提下为对象扩展功能; 动态地给一个对象添加一些额外的职责。就扩展功能而言,Decorator模式比生成子类方式更为灵活。
  • Façade 外观模式注重简化接口; 为子系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
  • Composite 组合模式,更是简化接口, 将“一对多”的关系转化为“一对一”的关系。将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。
  • Proxy 代理模式,为其他对象提供一个代理以控制对这个对象的访问。

posted on 2009-06-08 17:15:37 by ghj1976  评论(1) 阅读(2728)

 

     上周五参加Google开发者日,给我冲击最大的是Html5。对我的冲击主要有2点:

     1、Html 5 可以带来丰富的用户体验。

     开发者日中Google演示的用Html5开发的Wave(一个Mail的应用)就被Google玩的很炫。邮件、IM、博客、照片等功能融合在一起。特别是可以在一个邮件中,几个相关人能够协同讨论,不再像从前一样一个问题可以讨论N个邮件。从现场多次的掌声中可以看到这个东西很强大。它可以实现现在Flash\Silverlight才能提供的功能。

下面是 Wave 的一个截图

20090529-google_wave_concurrent_edit-517x580

图片来源自:http://google.org.cn/2009/05/29/google-wave-a-new-communication-platform-for-a-new-web-2/

     2、各种浏览器支持Html5的步伐很快。

Html5的规范不象之前,九几年就出来的规范,不久前普及,这次Html5的支持,进展很快。HTML 5还没有标准化,但Firefox、Chrome、Safari和Opera已经引入了它的元素。很难想象的是一个处于草案解决的规范,已经有众多浏览器支持了。一些支持信息如下:

html5

图片来源自: http://radar.oreilly.com/2009/05/google-bets-big-on-html-5.html 

 

小结

进展很快,功能强大,由于Google等大公司的推进,很快我们将能看到Html5的更多应用,这是一个值得关注的领域。

 

参看:

Google Wave会影响RIA/Silverlight吗?
http://www.infoq.com/cn/news/2009/06/Wave-Silverlight

谷歌开发者日:Google Wave将基于BSD协议开源
http://www.infoq.com/cn/news/2009/06/google-wave-opensource-bsd

Google I/O 2009现场视频之HTML 5之歌
http://google.org.cn/2009/06/02/song-of-html-50/

Google力挺HTML 5 或成未来应用核心
http://developer.51cto.com/art/200906/126709.htm

HTML 5 正式标准恐将2022年才能正式发布
http://developer.51cto.com/art/200809/89605.htm    

Firefox 3.1开始支持HTML 5 视频和音频
http://www.javaeye.com/news/3959-firefox-3-1-to-support-html-5-video-and-audio

posted on 2009-06-08 15:11:03 by ghj1976  评论(1) 阅读(2705)

 
2009年06月03日

我做的一个Windows Form 程序碰到一个很怪异的多线程情况,最后检查进去竟然是部分代码的数据库链接没有关闭导致的。

我的这个程序是多线程程序,每个线程不间断的从数据库中取得数据,然后对取出的数据进行处理,一直循环到没有需要处理的数据为至。每个线程的循环是上万次的,即,每个线程上万次的数据库链接打开操作。

这个程序碰到怪异的现象是:

在A服务器上,没有任何问题,在B服务器上程序开一个线程没有任何问题,开多个线程则只有一个线程没问题,其他线程都有问题。

对每一个线程都作 try catch 拦截,就会看到出错线程报如下错误:

超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

System.Data

   在 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)

   在 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)

   在 System.Data.SqlClient.SqlConnection.Open()

从这个异常就可以看到,是数据库链接对象池中没有可用的链接了。

再分析下去,就是其中一部分从数据库中读数据的代码,没有调用 SqlConnection.Close。

 

分析我这个程序出现的规律:

单线程,不主动调用 SqlConnection.Close

这时候竟然数据库链接池不会报没有可用资源:

数据库链接对象池的默认最大容量为100,单线程对数据库链接打开的请求超过10000的。

显然这种情况下,虽然没有手工SqlConnection.Close,但是这些数据库链接SqlConnection还是回到了数据库链接对象池中了。

多线程时,不主动调用 SqlConnection.Close。

只有一个线程在跑,其他线程都报上述错误。

显然,多线程时,数据库链接对象池都被一个线程占住了,其他线程获得不了可用分数据库链接。

 

这个多线程怪异的特征,之前一直没想到会是SqlConnection.Close导致的,一直在其他方面想可能的问题。这次经验教训后,心得就是:

  • try catch 只能拦截当前线程的异常,它拦截不到其他线程的。
  • 多人协作开发,并且程序经过多次修改bug后,完全有可能出现某些情况下,没有关闭数据库链接的情况,这种情况如何避免,是必须深思的一个问题。
  • 单线程,不主动关闭SqlConnection,有可能仍然不报错误,但是多线程下,就可能报错误了。

 

参考资料:

FIX: Error message when a "System.Data" thread tries to open a pooled connection in the .NET Framework 2.0: "Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool
http://support.microsoft.com/kb/948868

http://support.microsoft.com/kb/948868/en-us

 

使用连接池
http://msdn.microsoft.com/zh-cn/library/8xx3tyca(VS.80).aspx

Connection Pooling for the .NET Framework Data Provider for SQL Server
http://msdn.microsoft.com/en-us/library/8xx3tyca(vs.71).aspx

posted on 2009-06-03 13:40:34 by ghj1976  评论(1) 阅读(2795)

 
2009年05月08日

知识点:

  • Singleton 模式解决的是实体对象个数的问题。
  • 整个创建型设计模式,除了Singleton,其他4个都是解决“如何创建易变类的实体对象”的问题。
  • Factory Method,Abstract Factory ,Builder 都需要一个额外的工厂类来负责实例化“易变对象”
    • Factory Method 解决“单个对象”的需求变化。
    • Abstract Factory 解决“系列对象”的需求变化。
    • Builder 解决“对象部分”的需求变化。构造的算法骨架稳定,各个步骤易变。
  • Prototype 采用的“原型克隆”的方法来解决这个问题。(可以认为是一个特殊的工厂类)
  • Factory Method,Abstract Factory ,Prototype  这三个创建型模式相互转换的难度很低。能用Abstract Factory实行的,我们肯定也可以用Factory Method和Prototype  。如何区分他们的呢?
    • 容易 克隆的类才方便用 Prototype ;是否这个类可用MemberwiseClone,是否可序列化,反序列化?
    • 单个对象和多个对象来区分Factory Method,Abstract Factory

我们如何选择那个设计模式来创建“易变类”呢?

      如果遇到“易变类”,起初的设计通常是从Factory Method 开始,当遇到更多更复杂的变化时,再考虑重构为其他三种工厂模式(Abstract Factory ,Builder ,Prototype ),后这三种区别看上面的知识点。

参考资料:

李建忠老师Webcast讲解的“C#面向对象设计模式纵横谈”
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032328034&Culture=zh-CN

posted on 2009-05-08 16:24:24 by ghj1976  评论(0) 阅读(3040)

 
2009年04月29日

MemberwiseClone 方法创建一个浅表副本,具体来说就是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

下面的代码就是演示这个问题:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CloneDemo
{
    [Serializable]
    class DemoClass
    {
        public int i = 0;
        public int[] iArr = { 1, 2, 3 };

        public DemoClass Clone1()
        {
            return this.MemberwiseClone() as DemoClass;
        }

        public DemoClass Clone2()
        {
            MemoryStream stream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);
            stream.Position = 0;
            return formatter.Deserialize(stream) as DemoClass;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DemoClass a = new DemoClass();
            a.i = 10;
            a.iArr = new int[] { 8, 9, 10 };
            DemoClass b = a.Clone1();
            DemoClass c = a.Clone2();

            // 更改 a 对象的iArr[0], 导致 b 对象的iArr[0] 也发生了变化
              a.iArr[0] = 88;


            Console.WriteLine("MemberwiseClone");
            Console.WriteLine(b.i);
            foreach (var item in b.iArr)
            {
                Console.WriteLine(item);
            }


            Console.WriteLine("Clone2");
            Console.WriteLine(c.i);
            foreach (var item in c.iArr)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }
    }
}

posted on 2009-04-29 16:58:37 by ghj1976  评论(0) 阅读(2689)

 
2009年04月13日

Singleton模式是最简单的模式,比较汗颜的是自己一直以来使用的是单线程的Singleton模式,最近在听了李建忠老师的模式讲座录像后,才发现自己一直没注意到这点。这个录像讲座在后面给出了链接地址: C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)

下面内容整理自李建忠老师的讲课内容:

单线程的Singleton模式

    public class Singleton
    {
        private static Singleton instance;

        private Singleton() { }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                    instance = new Singleton();
                return instance;
            }
        }
    }

要点:

  • Singleton模式中的实例构造器可以设置为protected以允许子类派生。
  • Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
  • Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样跟Singleton模式的初衷违背。
  • Singleton模式只考虑到了对象创建的管理,并没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。
  • 上述代码不支持多线程环境,上述代码在多线程下,仍然有可能得到Singleton类的多个实例。

多线程的Singleton模式

    public class Singleton
    {
        private static volatile Singleton instance = null;

        private static object lockHelper = new object();

        private Singleton() { }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (lockHelper)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

代码说明:

  • volatile C#关键字作用,简单来说,编译器编译我们的代码时候,会对代码作一些优化,进而对代码进行了微调,使用volatile关键字就可以避免这个微调。继而严格意义上保证不会产生多线程。更详细的关于volatile 的说明,请看参考资料。
  • 双检查加锁模式。在lock之外和之内,我们做了instance是否为空的检查。这叫双检查。因为同步控制的时间太长了。双检查能够最高效地实现多线程安全的访问。

使用.net特有的支持多线程的单件模式代码

    public sealed class Singleton
    {
        public static readonly Singleton Instance = new Singleton();
        private Singleton() { }
    }

代码说明:

  • sealed 修饰符表示该类是密封类,不能被继承。你可以按需修改。
  • 这里readonly关键字只是不希望客户程序将Instance字段设置为null等不合理的值。
  • *** static *** = new Singleton(); 是使用了内联初始化技术,这部分初始化其实是在static Singleton()中执行的。即上面的代码相当于:
  •     public sealed class Singleton
        {
            public static readonly Singleton Instance;
            static Singleton()
            {
                Instance = new Singleton();
            }
            private Singleton() { }
        }
  • 上述代码在编译时,会使用一个名为beforefieldinit元数据标志。此标志使得运行库能够在任何时候执行类型构造函数方法,只要该方法在第一次访问该类型的静态字段之前执行即可。换句话说,beforefieldinit 为运行库提供了一个执行主动优化的许可。如果没有 beforefieldinit,运行库就必须在某个精确时间运行类型构造函数,即,恰好在第一次访问该类型的静态或实例字段和方法之前。
  • 静态构造器自身就可以保证,多线程情况下,系统就可以保证只有一个执行。

缺点:

  • 不支持参数化单件构造器。即静态构造器不支持参数,就导致我们无法利用静态构造器实现传参数的单件。

 

参考资料:

讲讲volatile的作用
http://blog.21ic.com/user1/2949/archives/2007/35599.html

Implementing the Singleton Pattern in C#
http://www.yoda.arachsys.com/csharp/singleton.html

初始化内联引用类型静态字段
http://msdn.microsoft.com/zh-cn/library/ms182275.aspx

通过七个关键编程技巧得益于静态内容
http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/us0501StaticsinNET.mspx?mfr=true

模式设计c#--创建型--Singleton
http://www.cppblog.com/mzty/archive/2006/01/03/2384.html

posted on 2009-04-13 10:52:39 by ghj1976  评论(1) 阅读(4394)

 
2009年04月03日

今天在看 EnterpriseLibrary 源文件时,看到如下的代码,这个代码可以比较经典的解释Thread.Sleep(0)的用途。代码如下:

Hashtable inMemoryCache;
CacheItem cacheItemBeforeLock = null;
// ..... 一些其他代码
// 通过循环,以获得 cacheItemBeforeLock 的控制权。
bool lockWasSuccessful; do { lock (inMemoryCache.SyncRoot) { // ..... lockWasSuccessful = Monitor.TryEnter(cacheItemBeforeLock); } if (lockWasSuccessful == false) { Thread.Sleep(0); } } while (lockWasSuccessful == false); try { // 对 cacheItemBeforeLock 作一些操作 // ..... } finally { Monitor.Exit(cacheItemBeforeLock); }
 
Thread.Sleep(0); 线程挂起0毫秒。表面看来这个代码是没啥意义的。
其实不然,挂起0毫秒的意义不在于0毫秒,而在于挂起2个字,线程挂起,其他线程就有机会优先执行。
上面的代码中,在Thread.Sleep(0);之前,这个线程跟其他线程争抢cacheItemBeforeLock的情况,就会因为这个挂起而得到解决。
参考:
关于Thread.Sleep(0) 
http://www.cnblogs.com/zzgfly/archive/2007/07/15/818426.html
Thread.Sleep 方法 (Int32)
http://msdn.microsoft.com/zh-cn/library/d00bd51t(VS.80).aspx
 

posted on 2009-04-03 14:12:23 by ghj1976  评论(1) 阅读(3358)

 
2009年04月01日

设置具体数据库启动Service Broker服务,如下图:

我这里试例数据库的名字为“ghj_Demo”,修改 Broker Enabled 属性为 true。

6801

你也可以用SQL 语句来修改,修改的SQL语句如下:

ALTER DATABASE ghj_Demo SET ENABLE_BROKER

确保你将使用的数据库帐户具有必需的权限

你在后面连接这个数据库的帐户,要确保对这个数据库具有 SUBSCRIBE、 QUERY 、NOTIFICATIONS 的权限。

下面就是一个简单的代码例子,来演示查询通知。这里用到一个我自己建立的表:

这个表结构如下:

CREATE TABLE [dbo].[User](
	[UserName] [nvarchar](20) NOT NULL,
	[Email] [nvarchar](50) NULL
) ON [PRIMARY]

GO

演示的控制台代码如下:

using System;
using System.Data;
using System.Data.SqlClient;

namespace Demo
{

    class Program
    {
        public static string connectionstring = "Data Source=.;Initial Catalog=ghj_Demo;Integrated Security=True";
        public void DoDependency()
        {
            using (SqlConnection conn = new SqlConnection(connectionstring))
            {
                // sql is a local procedure that returns
                // a paramaterized SQL string. You might want
                // to use a stored procedure in your application.
                string sql = "select [UserName] ,[Email] from dbo.[User]";


                SqlCommand cmd = new SqlCommand(sql, conn);
                // Ensure the command object does not have a notification object.
                cmd.Notification = null;

                //Notification specific code
                SqlDependency dep = new SqlDependency(cmd);
                dep.OnChange += new OnChangeEventHandler(TestEvent);


                conn.Open();
                SqlDataReader r = cmd.ExecuteReader();
                //Read the data here and close the reader
                r.Close();
                conn.Close();
                Console.WriteLine("DataReader Read...");
            }
        }


        void TestEvent(Object o, SqlNotificationEventArgs args)
        {
            // 注意:
            // 如果Server端在很短的时间内发生了大量的改动(比如用了一个循环Update了好多行),
            // OnChanged必须能迅速处理事件,否则它只会被触发一次。这个不是缺陷,
            // 因为一般OnChanged事件处理函数内都要执行类似刷新缓存的操作,它只触发一次,
            // 不会影响程序逻辑,却能提高程序性能。 

            Console.WriteLine("======================");
            Console.WriteLine("Event Recd");
            Console.WriteLine("Info:" + args.Info);
            Console.WriteLine("Source:" + args.Source);
            Console.WriteLine("Type:" + args.Type);
        }



        static void Main(string[] args)
        {
            // In order to use the callback feature of the
            // SqlDependency, the application must have
            // the SqlClientPermission permission.
            try
            {
                SqlClientPermission perm = new SqlClientPermission(
System.Security.Permissions.PermissionState.Unrestricted); perm.Demand(); } catch { throw new ApplicationException("No permission"); } try { SqlDependency.Stop(connectionstring); //Start the listener infrastructure on the client SqlDependency.Start(connectionstring); Program q = new Program(); q.DoDependency(); Console.WriteLine("Wait for Notification Event..."); Console.Read(); } finally { //Optional step to clean up dependency else it will fallback to automatic cleanup SqlDependency.Stop(connectionstring); } } } }

一些注意事项:摘自MSDN文档

使用查询通知功能的应用程序需要考虑下列特殊注意事项。

注意事项

说明

SQL Server 的服务帐户

对于使用本地系统帐户作为服务帐户的 SQL Server 实例,应用程序不会从其接收通知。

接收通知

无法在运行 Windows 95 或 Windows 98 的计算机上接收通知。

查询通知和事务

如果在某一事务内进行了多项影响具有已注册通知请求的一组数据的修改,则仅会发送单个通知事件。

快速更新和查询通知

使用查询通知的应用程序必须考虑到立即出现通知的情况。服务器上的数据更改时,通知消息将发送到相应的服务中介程序队列。 应用程序需要注册才能接收其他通知。 因此,如果多个应用程序快速更新某个数据集,应用程序在缓存刷新后,立即可以接收通知,检索数据,然后获取另一个更新通知。 编写使用查询通知的应用程序时必须考虑到此情况。 如果应用程序使用不断更新的数据,则可能更适合使用另一种数据缓存策略。

设置选项设置

在通知请求下执行 SELECT 语句时,提交请求的连接必须设置以下选项:

· ANSI_NULLS ON

· ANSI_PADDING ON

· ANSI_WARNINGS ON

· CONCAT_NULL_YIELDS_NULL ON

· QUOTED_IDENTIFIER ON

· NUMERIC_ROUNDABORT OFF

· ARITHABORT ON

 

编写通知查询语句的约束

您可以为 SELECT 和 EXECUTE 语句设置通知。 使用 EXECUTE 语句时,SQL Server 会为执行的命令而不是 EXECUTE 语句本身注册通知。 该命令必须满足 SELECT 语句的要求和限制。 当注册通知的命令包含多个语句时,数据库引擎会为批处理中的每个语句创建一个通知。

对满足以下要求的 SELECT 语句支持查询通知:

  • SELECT 语句中的提取的列必须显式声明,且表名称必须用由两部分组成的名称进行限定。 请注意,这意味着语句中引用的所有表都必须位于同一个数据库中。

  • 语句不能使用星号 (*) 或 table_name.* 语法来指定列。

  • 语句不能使用未命名的列或重复的列名称。

  • 语句必须引用一个基表。

  • SELECT 语句中的提取的列不能包含聚合表达式,除非该语句使用 GROUP BY 表达式。 在提供 GROUP BY 表达式的情况下,选择列表可以包含聚合函数 COUNT_BIG() 或 SUM()。 不过,不能为可以为 null 的列指定 SUM()。 语句不能指定 HAVING、CUBE 或 ROLLUP。

  • SELECT 语句中的提取的列用作简单表达式时不能出现多次。

  • 语句不能包含 PIVOT 或 UNPIVOT 运算符。

  • 语句不能包含 INTERSECT 或 EXCEPT 运算符。

  • 语句不能引用视图。

  • 语句不能包含以下任一项: DISTINCT、COMPUTE、COMPUTE BY 或 INTO。

  • 语句不能引用服务器全局变量 (@@variable_name)。

  • 语句不能引用派生表、临时表或表变量。

  • 语句不能引用其他数据库或服务器中的表或视图。

  • 语句不能包含子查询、外部联接或自联接。

  • 语句不能引用大型对象类型: text、ntext 和 image。

  • 语句不能使用 CONTAINS 或 FREETEXT 全文谓词。

  • 语句不能使用行集合函数,包括 OPENQUERY 和 OPENROWSET。

  • 语句不能使用以下任一集合函数: AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR 或 VARP。

  • 语句不能使用任何不确定性函数,包括排名和开窗函数。

  • 语句不能包含用户定义的聚合。

  • 语句不能引用系统表或视图,包括目录视图和动态管理视图。

  • 语句不能包含 FOR BROWSE 信息。

  • 语句不能引用队列。

  • 语句不能包含无法更改或无法返回结果的条件语句(例如 WHERE 1=0)。

sunmast 对查询通知的注意事情也有很多有价值的整理:
使用SQL Server 2005 Query Notification的几个注意事项
http://blog.joycode.com/sunmast/archive/2006/08/11/sql_2005_query_notification_comments_79814.aspx

 

参考资料:

剖析SQL Server 2005查询通知之基础
http://www.allwiki.com/wiki/%E5%89%96%E6%9E%90SQL_Server_2005%E6%9F%A5%E8%AF%A2%E9%80%9A%E7%9F%A5%E4%B9%8B%E5%9F%BA%E7%A1%80

Using SqlDependency for data change events
http://www.codeproject.com/KB/database/chatter.aspx

SQL Server 2005 Service Broker 初探
http://msdn.microsoft.com/zh-cn/library/ms345108.aspx

SQL Server 2005数据库开发详解
http://book.csdn.net/bookfiles/24/10024713.shtml

C# Windows 应用程序中实现 SQL Server 2005 查询通知
http://support.microsoft.com/kb/555893/zh-cn

SqlDependency changes for RTM [Sushil Chordia]
http://blogs.msdn.com/dataaccess/archive/2005/09/27/474447.aspx

.NET 2.0 SqlDependency快速上手指南
http://www.cnblogs.com/Xrinehart/archive/2006/07/27/461106.html

在 Windows 应用程序中使用 SqlDependency
http://msdn.microsoft.com/zh-cn/library/a52dhwx7(VS.80).aspx

Using SqlDependency in an ASP.NET Application 
http://msdn.microsoft.com/en-us/library/9dz445ks(VS.80).aspx

Minimum Database Permissions Required for SqlDependency
http://www.codeproject.com/KB/database/SqlDependencyPermissions.aspx

使用SQL Server 2005 Query Notification的几个注意事项
http://blog.joycode.com/sunmast/archive/2006/08/11/sql_2005_query_notification_comments_79814.aspx

posted on 2009-04-01 17:08:53 by ghj1976  评论(0) 阅读(3194)

 
2009年03月30日

一个简单问题:如下2种Html写法,那个加载速度快?

<!-- 写法1 -->
<div>
<div>内容代码2</div>
<div>内容代码3</div>
<div>内容代码4</div>
<div>内容代码5</div>
<div>内容代码6</div>
<div>内容代码7</div>
<div>内容代码8</div>
<div>内容代码9</div>
<div>内容代码10</div>
</div>

<!-- 写法2 -->
<div>内容代码2</div>
<div>内容代码3</div>
<div>内容代码4</div>
<div>内容代码5</div>
<div>内容代码6</div>
<div>内容代码7</div>
<div>内容代码8</div>
<div>内容代码9</div>
<div>内容代码10</div>

我的答案,写法2。当然,如果只是上面的写法,实际上这两种写法对性能的差别,可以忽略不计。

但是如果,上图的内容代码区域如果嵌入了一些不可控的因素,比如:外站的一些脚本出现在<div>内容代码7</div>中。写法1需要所有都加载完成才可以正常显示,写法2的内容2-6 不受这个影响。

 

更具体的来说:浏览器解析Html的规则必然是:

  • 当服务器向浏览器输出多少,浏览器就会解释多少,浏览器不可能解析没有给它的内容。
  • 源文件Body区域的每个Html标签,如果浏览器找不到这个标签的结束标志(一些html标签没有结束标志,但是需要浏览器去分析结束位置)。这个标签对应的内容,浏览器就难以正常显示。
  • 源文件Body区域的多个标签嵌套,需要所有被嵌套标签都加载完成,才能正常显示,这时候加载顺序是倒着的。举例:<div>1<div>2<div>3</div><div></div>这段源代码会先显示3,然后2, 最后1。因为加载div1时并没有找到它的结束标签</div>,于是它不加载继续解析源文件,在找到div2时,和上面一样也没有找到结束位置不做加载。然后是找到div3,div3有结束标签。 浏览器开始加载div3,之后,找到div2的结束标签,加载div2,以次类推,所以这时理论加载顺序为: 3 2 1 。
  • 如果浏览器的加载页面元素只是上面这样的工作原理,我们看到的很多页面的效果就是整个页面所有都加载完成才能显示出来。其实浏览器还有由一个特性,它可以去预测没有加载的内容。有些浏览器在打开一些网页的规程中,会把一些元素移位,最后才恢复正常,一部分原因就是这个事先预测在起作用。

 

再回到最初的问题:

一般美工在作页面时,会喜欢写法1的嵌套Html。如果一个夏姆,对用户体验要求高,同时预测到可能会在一些地方嵌入广告脚本会影响到页面显示,我会要求美工用方法2的方式来书写源文件,以保证用户体验。页面的设计,减少嵌套的层次,对页面的加载会好处多多的。

最后,我家儿子刚过一周岁,文章的最后祝福一下我家小宝贝。

 

参考资料:

<div>嵌套<div>后的显示速度问题
http://zhidao.baidu.com/question/7892633.html

关于DIV和表格的速度评论
http://x.discuz.net/viewthread-469261.html

把所有东西都放在一个大DIV里,显示速度问题。
http://zhidao.baidu.com/question/52404898.html

整个网页面用一个DIV包含起来好不好
http://zhidao.baidu.com/question/67452079.html

posted on 2009-03-30 14:42:12 by ghj1976  评论(2) 阅读(3926)

 
2009年03月19日

      网络负载平衡采用一种完全分布式的算法,根据传入客户端的 IP 地址和端口,以统计方式将其映射到群集主机。此进程的发生不需要主机间进行任何通信。当发现到达的数据包时,所有主机同时执行这种映射,以快速确定哪个主机应当处理这个程序包。这种映射一直保持不变,直到群集主机数发生更改时为止。与集中式负载平衡应用程序相比,网络负载平衡筛选算法处理数据包的效率更高,因为前者必须修改和重新传送数据包。

如下图:

  • 请求发送到所有NLB主机
  • 只有一台主机会处理,其他主机丢弃这个请求。
  • 此进程的发生不需要主机间进行任何通信。
  • 不需要修改和重新传送请求数据包。

 

cc756878_6526a396-cf25-4936-9474-827744f3ff9d(en-us)

这个统计算法在 Wlbs.sys 组件中实现。

有关这个算法细节可以搜索关键字:“Load Balancing Algorithm”

下面是一些相关文章链接:

How Network Load Balancing Algorithm works internally
http://www.codedigest.com/Articles/Windows%20and%20Clustering/49_How_Network_Load_Balancing_Algorithm_Works_Internally.aspx

 

      为了协调其操作,网络负载平衡主机在群集内周期性地交换检测信号。IP 多播允许主机监控群集状态。当群集状态更改时(例如当主机发生故障、离开或加入群集时),网络负载平衡将调用称作“聚合”的过程,在该过程中,主机交换数量有限的消息,以确定群集的新的一致状态,并为主机指定最高主机优先级,即作为新的默认主机。当所有群集主机在正确的新群集状态下取得一致后,它们将在 Windows 事件日志中记录聚合的完成。完成这个过程一般用不了 10 秒种。

      在聚合过程中,其余主机继续处理传入的网络通信。对工作主机的客户端请求不受影响。完成聚合后,将以故障主机为目标的通信重新分发给仍在工作的主机。经过负载平衡后的通信将在仍在工作的主机间得到重新划分,以便尽可能好地实现特定 TCP 或 UDP 端口的新的负载平衡。

      如果向群集添加了一个主机,则聚合允许该主机接收自己那份经过负载平衡的通信。群集的扩展不影响正在进行的群集操作,而且其实现过程对 Internet 客户端和服务器应用程序都是透明的。但是,当选择了“客户端相似性”时,它可能影响跨多个 TCP 连接的客户端会话,因为可能会将客户端重映射到连接间的不同群集主机。有关相似性的详细信息,请参阅网络负载平衡和状态可控的连接。

      网络负载平衡假定,主机在群集内正常工作的时间与它同其他群集主机交换检测信号的时间一样长。如果在多次检测信号交换中,其他主机都没有接收到来自任何成员的响应,则它们将启动聚合,重新分发本来应由失败主机处理的负载。

      对于消息交换时段以及启动聚合所需的丢失的消息数,您都可以进行控制。默认值设置分别为 1000 毫秒(1 秒)和 5 个丢失的消息交换时段。由于一般都不修改这些参数,所以无法通过“网络负载平衡属性”对话框配置它们。必要时,可以在注册表中手动调整它们。调整聚合参数对完成此操作的过程进行了描述。

如下图所示发生群机主机变更时的处理。

 

聚集前的NLB集群

cc756878_6c2499e2-a23d-4372-84e9-472f776f976e(en-us)

聚集后的NLB集群

cc756878_112a09ea-07b3-4147-a07b-e0dae0261879(en-us)

 

参考资料:

How Network Load Balancing Technology Works
http://technet.microsoft.com/en-us/library/cc756878.aspx

Appendix B - Network Load Balancing Technical Overview
http://technet.microsoft.com/en-us/library/bb734896.aspx

网络负载平衡的工作原理
http://technet.microsoft.com/zh-cn/library/cc738894.aspx

posted on 2009-03-19 09:30:34 by ghj1976  评论(0) 阅读(4618)

 
2009年03月18日

machineKey的作用在于下述场景:

  • ASP.net 使用 forms authentication 时的 cookie 数据的加密和解密。以确保这部分数据不会被篡改。
  • viewstate 数据的加密和解密。以确保这部分数据不会被篡改。
  • 使用进程外session(out-of-process session)时,对会话状态标识进行验证。

ASP.net 1.0 以及 ASP.net 1.1, 我们都可以在下面地址的文件中找到machineKey的配置信息:

%Windir%\Microsoft.NET\Framework\<version>\config\machine.config

不同的是 ASP.net 1.0 找到的是如下的配置信息

<machineKey 
   validationKey="AutoGenerate" 
   decryptionKey="AutoGenerate" 
   validation="SHA1"
/>

ASP.net 1.1 找到的是如下信息:

<machineKey 
   validationKey="AutoGenerate,IsolateApps" 
   decryptionKey="AutoGenerate,IsolateApps" 
   validation="SHA1"
/>

但是 ASP.net 2.0 , .net Framework 3.0 ,.net Framework 3.5 这些版本中,我们在

%Windir%\Microsoft.NET\Framework\<version>\config\

目录的  machine.config 和 web.config 中找不到machineKey的设置。

这是因为, ASP.net 2.0 中,machineKey 的默认设置没有写在配置文件中。

ASP.net 2.0 中,machineKey 的默认设置如下:

<machineKey 
   validationKey="AutoGenerate,IsolateApps" 
   decryptionKey="AutoGenerate,IsolateApps"    
   validation="SHA1" 
   decryption="Auto" 
/>

我们如果要修改machineKey的默认设置,就需要在必要的地方新加machineKey的配置节点。

产生一个可用的 machineKey 配置信息可以使用下面地址提供的工具:
http://www.aspnetresources.com/tools/keycreator.aspx

参考资料:

How To: Configure MachineKey in ASP.NET 2.0
http://msdn.microsoft.com/zh-cn/library/ms998288(en-us).aspx

machineKey 元素(ASP.NET 设置架构)
http://msdn.microsoft.com/zh-cn/library/w8h3skw9(VS.80).aspx
http://msdn.microsoft.com/en-us/library/w8h3skw9.aspx

posted on 2009-03-18 14:41:12 by ghj1976  评论(0) 阅读(4858)

 
2009年03月17日

ASP.net工作线程池

当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程。

一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求。如果一个同步请求成为 I/O bound(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求的线程在调用返回之前处于挂起状态。 这影响了可伸缩性,原因是线程池的可用线程是有限的。

这个数字的设置是在 machine.config 的 下述节点的 maxWorkerThreads 属性

<system.web>
	<processModel requestQueueLimit="num|Infinite" maxWorkerThreads="num"  />
</system.web>

maxWorkerThreads
按 CPU 配置用于进程的辅助线程的最大数目。例如,如果单处理器服务器上的该值为 25,ASP.NET 使用运行时 API 将进程限制设置为 25。在双处理器服务器上,该限制设置为 50。该属性的值必须等于或大于 httpRuntime 配置节中的 minFreeThread 属性设置。
该属性的范围是从 5 到 100。

ASP.net请求队列

上述设置中,还有一个队列设置,如下:


requestQueueLimit
指定队列中允许的请求数,超过此数目后,ASP.NET 将开始向新请求返回“503 - 服务器太忙”消息。

 

默认情况下,这个可用分线程数为1000。下图为IIS6和IIS7中这个参数的设置地方。

IIS 7 的可用线程数设置

IIS 6 的可用线程数设置

 

如果所有请求处理线程全部阻塞以等待 I/O 操作完成,则其他请求排入队列等待线程释放。

最好的情况是吞吐量减少,因为请求等待较长的时间才能得到处理。

最坏的情况则是该队列填满,并且 ASP.NET 因 503“Server Unavailable”错误使后续请求失败。

 

参考资料:

在服务器端 Web 代码中使用线程和生成异步处理程序
http://msdn.microsoft.com/zh-cn/library/aa686076.aspx

ASP.NET 2.0 中的异步页
http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx

IIS 6.0 架构
http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106572.aspx
http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106579.aspx


IIS 7.0 架构
http://blog.csdn.net/SKY_VID/archive/2008/03/04/2147732.aspx

 

了解ASP.NET底层架构
http://blog.csdn.net/fanweiwei/archive/2007/04/10/1558912.aspx

posted on 2009-03-17 13:37:57 by ghj1976  评论(0) 阅读(4426)

 

最近正在研究如何把CSDN的论坛WEB服务器实现负载平衡(NLB)。下面就是我整理资料笔记:

NLB 的工作原理

NLB算法的特点:

  • 在NLB群集中,每台服务器都会有一个属于自己的静态IP地址,同时NLB群集中的所有服务器还有一个共同的IP地址—NLB群集地址;
  • 当客户向NLB群集(NLB的虚拟IP地址)发起请求时,其实客户的请求数据包是发送到所有的NLB节点(即:NLB算法需要NLB群集中的所有主机都能看到发往群集的每一个数据包。),然后运行在NLB节点上的NLB服务根据同样的NLB算法来确定是否应该由自己进行处理,如果不是则丢弃客户的请求数据包,如果是则进行处理。 
  • 网络负载平衡使得单个子网上的所有群集主机可以同时检测群集 IP 地址的传入网络通信。在每个群集主机上,网络负载平衡驱动程序充当群集适配器驱动程序和 TCP/IP 堆栈间的过滤器,以便在主机间分配通信。

要确保上面算法的特点,单播(Unicast ),多播(Multicast)实现NLB就会有以下的特点:

NLB中的单播(Unicast)

      在单播模式下,NLB重新对每个NLB节点中启用NLB的网络适配器分配MAC地址(此MAC地址称为群集MAC地址),并且所有的NLB节点均使用相同的MAC地址(均使用群集MAC地址),同时NLB修改所有发送的数据包中的源MAC地址,确保使交换机不能将此群集MAC地址绑定在某个端口上。

      工作在单播模式下的NLB可以在所有网络环境下正常运行,但是由于它的工作特性,具有以下两个限制:

  • 由于NLB所使用的群集MAC地址没有绑定在某个具体的交换机端口上,所以所有的NLB通讯均通过在交换机的所有端口上广播进行,而不管此端口是否连接了NLB节点,这造成了额外的网络流量负担;
  • 由于所有的NLB节点具有相同的MAC地址,NLB节点之间不能通过自己原有的专用IP地址进行通讯。

     单播模式的优点也很明显:它可以无缝地与大多数路由器和交换机协同工作。

     如下图所示:

Image1189

单播的其他注意项:

  • 在Windows server 2003 SP1中,微软修改了NLB单播模式的驱动,从而支持阵列成员通过自己原有的专用IP地址进行通讯,详细信息请参见KB898867,Unicast NLB nodes cannot communicate over an NLB-enabled network adaptor in Windows Server 2003。
  • 若我们在NLB创建时选择单播的模式,在“群集IP配置”中的“网络地址”是以“02 - BF”开头,后面紧跟IP地址的十六进制表示,该网络地址与实际主机的MAC地址相同,后续加入的主机也将修改为此MAC地址。

参考:

单播模式下的单个网络适配器
http://technet.microsoft.com/zh-cn/library/cc757150.aspx
单播模式下的多个网络适配器
http://technet.microsoft.com/zh-cn/library/cc786134.aspx

NLB中的多播(Multicast)

      在多播模式下,NLB不会修改NLB节点启用NLB的网络适配器的MAC地址,而是为它再分配一个二层多播MAC地址专用于NLB的通讯(此MAC地址称为群集MAC地址),这样NLB节点之间可以通过自己原有的专用IP地址进行通讯。

      但是在多播模式中,NLB节点发送的针对群集IP地址MAC地址ARP(Address Resolution Protocol,地址解析协议)请求的ARP回复会将群集IP地址映射到多播MAC地址,而许多路由器或者交换机(包括CISCO的产品)会拒绝这一行为。当出现这种情况时,你必须在路由器和交换机上手动添加静态映射,将群集IP地址映射到群集的多播MAC地址。

         这种模式的优点是可以通过在交换机的“内容可寻址存储器”(CAM) 表中创建静态项,从而使得入站流量仅到达群集中的主机。

      还有一个缺点就是很多路由器不会自动将单播 IP 地址(群集的虚拟 IP 地址)与多播 MAC 地址关联起来。如果进行静态配置的话,一些路由器可以存在这种关联。若我们在NLB创建时选择多播的模式,在“群集IP配置”中的“网络地址”是以“03 -BF”开头,后面紧跟IP地址的十六进制表示。

      如下图所示:

 

 

Image1193

 

 

IGMP Multicast(IGMP多播)

      NLB算法需要NLB群集中的所有主机都能看到发往群集的每一个数据包。NLB不允许交换机将群集的MAC地址关联到交换机的某个特定端口,从而实现了这个目的。但是,这种做法也会带来不想要的副作用,就是发往NLB群集的所有数据包会在交换机上的所有端口上造成数据“洪水”。这不仅非常麻烦,而且必将会造成网络资源的浪费。

      为了解决这个问题,一个被称作IGMP支持的新特性被引入到了Windows Server 2003之中。该特性有助于将数据“洪水”限制到交换机上与NLB计算机相连接的端口上。通过这种方式,非NLB的计算机不会看到发往NLB群集的数据,而与此同时,所有的NLB计算机都可以看到发往群集的数据,因此满足了NBL算法的要求。但是,应该指出的是:IGMP支持只有在NLB被配置多播(multicast)模式时才能启用。

      在选择多播模式时,后面还有个复选项“IGMP Multicast(IGMP多播)”,若复选此项,就像多播操作模式一样,NLB 保留原厂 MAC 地址不变,但是向网络适配器中增加了一个 IGMP 多播地址。此外,NLB 主机会发出这个组的 IGMP 加入消息。如果交换机探测到这些消息,它可以使用所需的多播地址来填充自己的 CAM 表,这样入站流量就不会扩散到 VLAN 上的所有端口。这是这种群集模式的主要优点。缺点是有一些交换机不支持 IGMP 探测。除此之外,路由器仍然支持单播 IP 地址到多播 MAC 地址的转换。在IGMP多播模式下,将采用“01 – 00 - 5E”开头的MAC地址。在多播的模式下,实体主机之间可以互相通信。

如下图所示:

cc758275_d1687ea3-0f58-46ce-ae65-208ee3aab8dc(en-us)

 

NLB对路由器的要求

当群集已配置为在多播模式下工作时,如果网络负载平衡客户端正在通过路由器访问一个群集,请确保路由器满足以下要求:

  • 接受地址解析协议 (ARP) 应答,此应答在 ARP 结构的有效负载部分有一个媒体访问控制 (MAC) 地址,但正如以太网报头所确定的,它看上去像来自具有另一个 MAC 地址的站点。
  • 接受单播 IP 地址的 ARP 应答,此应答在其 ARP 结构的有效负载部分有一个多播 MAC 地址。

单播模式对路由器没有要求。

 

 

参考:

多播模式下的单个网络适配器
http://technet.microsoft.com/zh-cn/library/cc759683.aspx

多播模式下的多个网络适配器
http://technet.microsoft.com/zh-cn/library/cc779600.aspx

 

附:单播(Unicast),多播(Multicast),广播(Broadcast) 的区别:

单播:

主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。但由于其能够针对每个客户的及时响应,所以现在的网页浏览全部都是采用IP单播协议。网络中的路由器和交换机根据其目标地址选择传输路径,将IP单播数据传送到其指定的目的地。
单播的优点:
1. 服务器及时响应客户机的请求
2. 服务器针对每个客户不通的请求发送不通的数据,容易实现个性化服务。
单播的缺点:
1. 服务器针对每个客户机发送数据流,服务器流量=客户机数量×客户机流量;在客户数量大、每个客户机流量大的流媒体应用中服务器不堪重负。
2. 现有的网络带宽是金字塔结构,城际省际主干带宽仅仅相当于其所有用户带宽之和的5%。如果全部使用单播协议,将造成网络主干不堪重负。现在的P2P应用就已经使主干经常阻塞,只要有5%的客户在全速使用网络,其他人就不要玩了。而将主干扩展20倍几乎是不可能。

多播(组播):

主机之间“一对一组”的通讯模式,也就是加入了同一个组的主机可以接受到此组内的所有数据,网络中的交换机和路由器只向有需求者复制并转发其所需数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择的复制并传输数据,即只将组内数据传输给那些加入组的主机。这样既能一次将数据传输给多个有需要(加入组)的主机,又能保证不影响其他不需要(未加入组)的主机的其他通讯。
组播的优点:
1. 需要相同数据流的客户端加入相同的组共享一条数据流,节省了服务器的负载。具备广播所具备的优点。
2. 由于组播协议是根据接受者的需要对数据流进行复制转发,所以服务端的服务总带宽不受客户接入端带宽的限制。IP协议允许有2亿6千多万个(268435456)组播,所以其提供的服务可以非常丰富。
3. 此协议和单播协议一样允许在Internet宽带网上传输。
组播的缺点:
1.与单播协议相比没有纠错机制,发生丢包错包后难以弥补,但可以通过一定的容错机制和QOS加以弥补。
2.现行网络虽然都支持组播的传输,但在客户认证、QOS等方面还需要完善,这些缺点在理论上都有成熟的解决方案,只是需要逐步推广应用到现存网络当中。

广播:

主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。
广播的优点:
1. 网络设备简单,维护简单,布网成本低廉
2. 由于服务器不用向每个客户机单独发送数据,所以服务器流量负载极低。
广播的缺点:
1.无法针对每个客户的要求和时间及时提供个性化服务。
2. 网络允许服务器提供数据的带宽有限,客户端的最大带宽=服务总带宽。例如有线电视的客户端的线路支持100个频道(如果采用数字压缩技术,理论上可以提供500个频道),即使服务商有更大的财力配置更多的发送设备、改成光纤主干,也无法超过此极限。也就是说无法向众多客户提供更多样化、更加个性化的服务。
3. 广播禁止在Internet宽带网上传输。

参考资料: 

Load Balancing and ASP.NET
http://www.hanselman.com/blog/LoadBalancingAndASPNET.aspx

Web Farming with the Network Load Balancing Service in Windows Server 2003
http://www.west-wind.com/presentations/loadbalancing/NetworkLoadBalancingWindows2003.asp

网络负载平衡算法 Works 内部怎样
http://support.microsoft.com/kb/556068/zh-cn?spid=3198&sid=770

WEB farm - Load Balancing in Asp.net
http://www.c-sharpcorner.com/UploadFile/gopenath/Page107182007032219AM/Page1.aspx

How to test web load balance
http://www.cnblogs.com/oscarxie/archive/2008/05/20/1203157.html

将asp.net迁移到Load Balance和NAS上的步骤
http://blog.joycode.com/hopeq/archive/2006/03/29/73762.aspx

微软知识库中的关于负载均衡的HowTo文章汇总
http://support.microsoft.com/ph/3198/zh-cn?sid=770&aid=1&GSA_AC_More1

TechNet 关于 网络负载平衡群集  的内容
http://technet.microsoft.com/zh-cn/library/cc759510.aspx     中文
http://technet.microsoft.com/en-us/library/cc759510.aspx     英文

下面文章中间谈到了负载均衡的工作原理
http://technet.microsoft.com/zh-cn/library/aa998796%28EXCHG.65%29.aspx

NLB配置中单播与多播区别
http://hi.baidu.com/hneli/blog/item/656725d3e5471433970a16bd.html

NLB群集
http://blog.sina.com.cn/s/blog_4b611a45010009hh.html

Using NLB with ISA Server Part 2: Layer 2 Fun with Unicast and Multicast Modes
http://www.isaserver.org/articles/basicnlbpart2.html

IP多播概述
http://www.microsoft.com/china/technet/community/columns/cableguy/cg0202.mspx

TCP/IP学习笔记之九 --- 广播和多播
http://blog.csdn.net/kmajian/archive/2008/11/27/3389667.aspx

网络负载平衡关键特性
http://technet.microsoft.com/en-us/library/cc758275.aspx

Network Load Balancing
http://www.msxfaq.de/verschiedenes/nlb.htm

Network Load Balancing Technical Overview
http://technet.microsoft.com/zh-cn/library/bb742455(en-us).aspx

网络技术基础知识一之ARP协议概说
http://cisco.chinaitlab.com/TCP/38035.html

posted on 2009-03-17 13:20:44 by ghj1976  评论(0) 阅读(5206)

 
2009年03月13日

在建立存储过程前,我习惯于先检查存储过程是否存在,如果存在就建立,然后再创建。

这个检查的过程,现在有2种习惯写法,如下:
if exists (
	select * from information_schema.routines where specific_name = 'WorkOrdersForBlade' and specific_schema = 'dbo')
	begin
		drop procedure dbo.workordersforblade
	end
go

或者

if exists (
	select * from sysobjects where type = 'p' and name = 'WorkOrdersForBlade')
	begin
		drop  procedure  dbo.workordersforblade
	end

go

information_schema.routines 是SQL Server 2000开始新加的系统视图,它是以 sysobjects 和 syscolumns 系统表为基础建立的系统视图。它的字段更具备可读性。

用上面那个写法都没有问题。 在SQL Server 2005 以及 2008 的默认模板中,使用的是第一种写法。

显然,我们最好用经过整合后,更具备可读性的视图 information_schema.routines 。

参考资料:

SQL Server 2008 联机丛书 对routines 视图的介绍
http://msdn.microsoft.com/zh-cn/library/ms188757.aspx
http://msdn.microsoft.com/en-us/library/ms188757.aspx

数据库中User和Schema的关系
http://blog.csdn.net/yanjiangbo/archive/2007/09/12/1782576.aspx

ROUTINES
http://www.yesky.com/imagesnew/software/tsql/ts_ia-iz_3kq1.htm

posted on 2009-03-13 10:38:15 by ghj1976  评论(1) 阅读(4048)

 
2009年03月12日

比如我们有如下图一的文档,我们希望把他们每五行合并成一行,即图二。

54301

(图一)

54302

(图二)

我们就可以用如下图的替换选项来实现:

54303

即,查找内容为

\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n

替换内容为

\1\2\3\4\n

这些正则表达式的写法,直接看查找内容和替换内容边的下拉按钮就可以很方便的获得提示,如下图:

54304

54305

posted on 2009-03-12 10:01:02 by ghj1976  评论(0) 阅读(3882)

 
2009年03月11日

公司正在统一存储过程的编写规范,为了更宜用,我们就修改了SQL Server Management Studio 和 Microsoft Visual Studio 2008 的模板文件。

SQL Server Management Studio 的模板文件所在的目录请参看我之前的博客:

改变 SQL Server Management Studio的模板

Visual Studio 2008 的DataBase Project(如下这个数据库项目)的模板则在

C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\Templates\Database Project Items  这个目录下。

注意:这跟其他类型项目的模板不是一个目录。

401

我这里要修改的模板就是下面方式建立的存储过程的模板。

402

额外多说一句,我是通过下面这个工具找到这个目录的。

Process Monitor
v2.03 (December 10, 2008)
Monitor file system, Registry, process, thread and DLL activity in real-time.

参考资料:

vs2008修改模板-自定义版权信息

posted on 2009-03-11 14:51:39 by ghj1976  评论(0) 阅读(3876)