博客

  • 免费SSL/https/数字证书

    Wosign(沃通)免费证书申请 http://freessl.wosign.com/freessl申请免费证书

    免费SSL证书Let’s Encrypt安装使用教程 官网https://letsencrypt.org/

    startssl免费证书申请 https://www.startssl.com/Account

  • C#语法糖(Csharp Syntactic sugar)大汇总(转)

    点评:这是10年的一篇网络文章,现在看看,发现也是值得滴。语法糖,还是要了解一下,万一别人用了,看不懂,这不很尴尬么~~

    ———————————————

    首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。这让java开发人员羡慕不已,呵呵。

    1.  经过简化的Property

    早些时候我们这样声明Property

    private string _myName;

    public string MyName

    {

    get { return _myName; }

    set { _myName = value; }

    }

    千篇一律的这样声明,没有多大意义,于是C#的设计人员将这个千篇一律的工作交给了编译器帮我们做了,我们现在可以这样声明

    public string MyName { get; set; }

    当然他不会牺牲灵活性,我们可以单独给get或者set设定访问限制符,例如

    public string MyName { get; protected internal set; }

    2.  经过两次变异的委托写法

    在.net 1.1时我们不得不声明方法后才在委托中使用,在.net 2.0之后我们可以使用匿名委托,他不单可以简化写法,还可以在匿名委托中访问范围内的变量;再后来拉姆达表达式来了,写法就更简便了。

    class MyClass

    {

    public delegate void DoSomething(int a);

    //定义方法委托

    private void DoIt(int a) {

    Console.WriteLine(a);

    }

    private void HowtoDo(DoSomething doMethod,int a) {

    doMethod(a);

    }

    public static void Main(string[] args) {

    MyClass mc = new MyClass();

    //调用定义的方法委托

    mc.HowtoDo(new DoSomething(mc.DoIt), 10);

    int x = 10;

    //使用匿名委托

    mc.HowtoDo(delegate(int a){

    Console.WriteLine(a + x);

    },10);

    //使用lamda表达式

    mc.HowtoDo(a=>Console.WriteLine(a+x),10);

    Console.ReadLine();

    }

    }

    3.  集合类的声明

    之前我们声明一个List并给list赋初始值,必须得这么写:

    List<string> list = new List<string>();

    list.Add("a一");

    list.Add("b二");

    list.Add("c三");

    现在不需要了,直接写就可以了

    List<string> list = new List<string> {

    "def","OK"

    };

    4.  集合类各个项的操作

    我们为了逐个处理集合中的项,需要这么写:

    foreach (string item in list)

    {

    Console.WriteLine(item);

    }

    现在不需要了,这样就可以了

    list.ForEach(a => Console.WriteLine(a));

    代码是不是清爽了很多。

    5.  using == try finally

    为了在使用完毕时释放资源,我们经常要用using,using实质上就是try fiannaly的一个语法糖而已。例如

    StreamWriter sw = null;

    try

    {

    sw = new StreamWriter("d:\abc.txt");

    sw.WriteLine("test");

    }

    finally {

    if(sw!= null) sw.Dispose();

    }

    上面的代码可以简化为:

    using (var sw = new StreamWriter("d:\abc.txt")) {

    sw.WriteLine("test");

    }

    6.  可爱的var

    var的意义时不必写声明的类型,编译器会根据后面对var的赋值判断它的类型,var的类型一旦确认就不能再改变,它只能作为局部变量使用,不能用做字段也不能用做参数声明。

    例如:

    var writer = new StreamWriter(path);

    for(var i=0;i<100;i++){}

    7.  问号的演变

    老掉牙的一个问号+冒号

    var b = 3;

    var a = b > 9?b.ToString():”0”+b;

    新宝宝两个问号 ??,它表示左边的变量如果为null则值为右边的变量,否则就是左边的变量值

    string a = null;

    var b = a??””;

    8.  类型实例化的语法糖

    public class Abc

    {

    public int ID { get; set; }

    public string Name { get; set; }

    public string Url { get; set; }

    }

    我们没有为上面的类声明构造函数,但是我们可以像下面的形式来实例化它

    public static void Main(string[] args) {

    var abc = new Abc{

    ID=1,

    Name="yukaizhao",

    Url="http://yukaizhao.cnblogs.com/"

    };

    }

    9.  传说中的扩展方法

    在c#3.5时引入了扩展方法,我们可以在不修改类源码的情况下给类增加实例方法,这个很有意义。它的实质也是一种语法糖的实现

    例如我们给String类扩展一个IsNumber的方法:

    public static class StringExt {

    static private Regex regexNumber = new Regex("\\d+");

    static public bool IsNumber(this string input)

    {

    if (string.IsNullOrEmpty(input))

    {

    return false;

    }

    return regexNumber.IsMatch(input);

    }

    }

    我们可以在String实例上调用这个方法了

    1

    2

    var abc = “123”;

    var isNumber = abs.IsNumber();

    10.使用匿名类

    1

    2

    3

    var a = new {

    ID = 1,Name=”yukaizhao”,BlogUrl=”http://www.cnblogs.com/yukaizhao/”

    };

    匿名类在linq to sql或者entity framework中返回查询数据时很好用。

    如果大家还有更多的语法糖,欢迎分享。同时希望大家享受语法糖,因为他可以给我们带来方便,请不要对它嗤之以鼻,也没必要对它嗤之以鼻。

    微博:http://weibo.com/yukaizhao 推荐 牧童*红杏*墙

    转自:http://www.cnblogs.com/yukaizhao/archive/2010/05/25/csharp-Syntactic-sugar.html

  • StackOverflow程序员推荐:每个程序员都应读的30本书(转)

    全文转,放点个人评论:其中有一两本是看过的,没有太大的印象了。不管写得多好多牛B,随着时间的流逝,都over了。

    ——————————————-

     

    “如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西。”

    很多程序员响应,他们在推荐时也写下自己的评语。以前就有国内网友介绍这个程序员书单,不过都是推荐数 Top 10的书。其实除了前10本之外,推荐数前30左右的书籍都算经典,伯乐在线整理编译这个问答贴,同时摘译部分推荐人的评语。下面就按照各本书的推荐数排列。

    1. 《代码大全》史蒂夫·迈克康奈尔

    推荐数:1684

    code complete 代码大全

    “优秀的编程实践的百科全书,《代码大全》注重个人技术,其中所有东西加起来,就是我们本能所说的“编写整洁的代码”。这本书有50页在谈论代码布局。” —— Joel Spolsky

    对于新手来说,这本书中的观念有点高阶了。到你准备阅读此书时,你应该已经知道并实践过书中99%的观念。– esac

    2. 《程序员修炼之道》

    推荐数:1504

    Pragmatic Programmer 程序员修炼之道

    对于那些已经学习过编程机制的程序员来说,这是一本卓越的书。或许他们还是在校生,但对要自己做什么,还感觉不是很安全。就像草图和架构之间的差别。虽然你在学校课堂上学到的是画图,你也可以画的很漂亮,但如果你觉得你不太知道从哪儿下手,如果某人要你独自画一个P2P的音乐交换网络图,那这本书就适合你了。—— Joel

    3. 《计算机程序的构造和解释》

    推荐数:916

    Structure and Interpretation of Computer Programs 计算机程序的构造和解释

    就个人而言,这本书目前为止对我影响醉倒的一本编程书。

    《代码大全》、《重构》和《设计模式》这些经典书会教给你高效的工作习惯和交易细节。其他像《人件集》、《计算机编程心理学》和《人月神话》这些书会深入软件开发的心理层面。其他书籍则处理算法。这些书都有自己所属的位置。

    然而《计算机程序的构造和解释》与这些不同。这是一本会启发你的书,它会燃起你编写出色程序的热情;它还将教会你认识并欣赏美;它会让你有种敬畏,让你难以抑制地渴望学习更多的东西。其他书或许会让你成为一位更出色的程序员,但此书将一定会让你成为一名程序员。

    同时,你将会学到其他东西,函数式编程(第三章)、惰性计算、元编程、虚拟机、解释器和编译器。

    一些人认为此书不适合新手。个人认为,虽然我并不完全认同要有一些编程经验才能读此书,但我还是一定推荐给初学者。毕竟这本书是写给著名的6.001,是麻省理工学院的入门编程课程。此书或许需要多做努力(尤其你在做练习的时候,你也应当如此),但这个价是对得起这本书的。

    你还不确信么?那就读读第一版的前言或序言。网上有免费的电子版。-Antti Sykäri

    4. 《C程序设计语言》

    推荐数:774

    The C Programming Language C程序设计语言

    这本书简洁易读,会教给你三件事:C 编程语言;如何像程序员一样思考;底层计算模型。(这对理解“底层”非常重要)—— Nathan

    5. 《算法导论》

    推荐数:671

    Introduction to algorithms 算法导论

    《代码大全》教你如何正确编程;《人月神话》教你如何正确管理;《设计模式》教你如何正确设计……

    在我看来,代码只是一个工具,并非精髓。开发软件的主要部分是创建新算法或重新实现现有算法。其他部分则像重新组装乐高砖块或创建“管理”层。我依然梦想这样的工作,我的大部分时间(>50%)是在写算法,其他“管理”细节则留给其他人…… —— Ran Biron

    6. 《重构:改善既有代码的设计》

    推荐数:617

    Refactor 重构:改善既有代码的设计

    我想我不得不推荐《重构》:改进现有代码的设计。—— Martin

    我必须承认,我最喜欢的编程语录是出自这本书:任何一个傻瓜都能写出计算机能理解的程序,而优秀的程序员却能写出别人能读得懂的程序。—— Martin Fowler

    7. 《设计模式》

    推荐数:617

    Design Patterns 设计模式

    就我而言,我认为四人帮编著的《设计模式》是一本极为有用的书。虽然此书并不像其他建议一样有关“元”编程,但它强调封装诸如模式一类的优秀编程技术,因而鼓励其他人提出新模式和反模式(antipatterns),并运用于编程对话中。—— Chris Jester-Young

    8. 《人月神话》

    推荐数:588

    The Mythical Man-Month 人月神话

    9. 《计算机程序设计艺术》

    推荐数:542

    The Art of Computer Programming 计算机程序设计艺术

    这是高德纳倾注心血写的一本书。—— Peter Coulton

    10. 《编译原理》(龙书)

    推荐数:462

    Compilers: Principles, Techniques, and Tools 编译原理:原理、技术与工具

    我很奇怪,居然没人提到龙书。(或许已有推荐,我没有看到)。我从没忘过此书的第一版封面。此书让我知道了编译器是多么地神奇绝妙。- DB

    11. 《深入浅出设计模式》

    推荐数:445

    我知道四人帮的《设计模式》是一本标准书,但倒不如先看看这部大部头,此书更为简易。一旦你了解了解了基本原则,可以去看四人帮的那本圣经了。- Calanus

    12. 《哥德尔、艾舍尔、巴赫书:集异璧之大成》

    推荐数:437

    如果下昂真正深入阅读,我推荐道格拉斯·侯世达(Douglas Hofstadter)的《哥德尔、艾舍尔、巴赫书》。他极为深入研究了程序员每日都要面对的问题:递归、验证、证明和布尔代数。这是一本很出色的读物,难度不大,偶尔有挑战,一旦你要鏖战到底,将是非常值得的。 – Jonik

    13. 《代码整洁之道》

    推荐数:329

    虽然《代码整洁之道》和《代码大全》有很多共同之处,但它有更为简洁更为实际的清晰例子。 – Craig P. Motlin

    14. 《Effective C++》和《More Effective C++》

    推荐数:297

    在我职业生涯早期,Scott Meyer的《Effective C++》和后续的《More Effective C++》都对我的编程能力有着直接影响。正如当时的一位朋友所说,这些书缩短你培养编程技能的过程,而其他人可能要花费数年。

    去年对我影响最大的一本书是《大教堂与市集》,该书教会我很有关开源开发过程如何运作,和如何处理我代码中的Bug。 – John Channing

    15. 《编程珠玑》

    推荐数:282

    尽管我不得不羞愧地承认,书中一半的东西我都没有理解,但我真的推荐《编程珠玑》,书中有些令人惊奇的东西。 – Matt Warren

    16. 《修改代码的艺术》by Michael Feathers

    我认为没有任何一本书能向这本书一样影响了我的编程观点。它明确地告诉你如何处理其他人的代码,含蓄地教会你避免哪些(以及为什么要避免)。- Wolfbyte

    同意。很多开发人员讨论用干净的石板来编写软件。但我想几乎所有开发人员的某些时候是在吃其他开发人员的狗食。– Bernard Dy

    17. 《编码:隐匿在计算机软硬件背后的语言》

    我推荐Charles Petzold的《编码》。在这个充满工具和IDE的年代,很多复杂度已经从程序员那“抽取”走了,这本书一本开眼之作。 – hemil

    18. 《禅与摩托车维修艺术 / Zen and the Art of Motorcycle Maintenance》

    对我影响最大的那本书是 Robert Pirsig 的《禅与摩托车维修艺术》。不管你做什么事,总是要力求完美,彻底了解你手中的工具和任务,更为重要的是,要有乐趣(因为如果你做事有乐趣,一切将自发引向更好的结果)。 – akr

    (编注:关于这本书,也可以看看阮一峰的读后感。)

    19. 《Peopleware / 人件集:人性化的软件开发》

    Demarco 和 Lister 表明,软件开发中的首要问题是人,并非技术。他们的答案并不简单,只是令人难以置信的成功。第二版新增加了八章内容。 – Eduardo Molteni

    20. 《Coders at Work / 编程人生》

    一本非常有影响力的书,可以从中学到一些业界顶级人士的经验,了解他们如何思考并工作。 – Jahanzeb Farooq

    21. 《Surely You’re Joking, Mr. Feynman! / 别闹了,费曼先生!》

    虽然这本书可能有点偏题,但不管你信不信,这本书曾在计算机科学专业课程的阅读列表之上。一个优秀的角色模型,一本有关好奇心的优秀书籍。 – mike511

    22. 《Effective Java 中文版》

    此书第二版教你如何编写漂亮并高效的代码,虽然这是一本Java书,但其中有很多跨语言的理念。 – Marcio Aguiar

    23. 《Patterns of Enterprise Application Architecture / 企业应用架构模式》

    很奇怪,还没人推荐 Martin Fowler 的《企业应用架构模式》- levi rosol

    24. 《The Little Schemer》和《The Seasoned Schemer》 nmiranda

    这两本是LISP的英文书,尚无中文版。美国东北大学网站上也有电子版。

    25. 《交互设计之路》英文名:《The Inmates Are Running The Asylum: Why High Tech Products Drive Us Crazy and How to Restore the Sanity》该书作者:Alan Cooper,人称Visual Basic之父,交互设计之父。

    本书是基于众多商务案例,讲述如何创建更好的、高客户忠诚度的软件产品和基于软件的高科技产品的书。本书列举了很多真实可信的实际例子,说明目前在软件产品和基于软件的高科技产品中,普遍存在着“难用”的问题。作者认为,“难用”问题是由这些产品中存在着的高度“认知摩擦”引起的,而产生这个问题的根源在于现今软件开发过程中欠缺了一个为用户利益着想的前期“交互设计”阶段。“难用”的产品不仅损害了用户的利益,最终也将导致企业的失败。本书通过一些生动的实例,让人信服地讲述了由作者倡导的“目标导向”交互设计方法在解决“难用”问题方面的有效性,证实了只有改变现有观念,才能有效地在开发过程中引入交互设计,将产品的设计引向成功。

    本书虽然是一本面向商务人员而编写的书,但也适合于所有参与软件产品和基于软件的高科技产品开发的专业人士,以及关心软件行业和高科技行业现状与发展的人士阅读。

    他还有另一本中文版著作:《About Face 3 交互设计精髓》

    26. 《Why’s (Poignant) Guide to Ruby 》

    如果你不是程序员,阅读此书可能会很有趣,但如果你已经是个程序员,可能会有点乏味。

    27.《Unix编程艺术》

    It is useful regardless operating system you use. – J.F. Sebastian
    不管你使用什么操作系统,这本书都很有用。 – J.F. Sebastian

    28. 《Practices of an Agile Developer / 高效程序员的45个习惯:敏捷开发修炼之道》

    45个习惯,分为7个方面:工作态度、学习、软件交付、反馈、编码、调试和协作。

    每一个具体的习惯里,一开始提出一个谬论,然后展开分析,之后有正队性地提出正确的做法,并设身处地地讲出了正确做法给你个人的“切身感受”,最后列出几条注意事项,帮助你修正自己的做法(“平衡的艺术”)。

    29. 《Test-Driven Development by Example. / 测试驱动开发》

    前面已经提到的很多书都启发了我,并影响了我,但这本书每位程序员都应该读。它向我展示了单元测试和TDD的重要性,并让我很快上手。 – Curro

    我不关心你的代码有多好或优雅。如果你没有测试,你或许就如同没有编写代码。这本书得到的推荐数应该更高些。人们讨论编写用户喜欢的软件,或既设计出色并健壮的高效代码,但如果你的软件有一堆bug,谈论那些东西毫无意义。– Adam Gent

    30. 《Don’t Make Me Think / 点石成金:访客至上的网页设计秘笈》

    取决于你所追求的目标。我喜欢《代码大全》是因纯编程,《点石成金》是一本有关UI设计的卓越书籍。 – Justin Standard

  • 不用IDE写C#的Hello World(转)

    作者: zhangweiwen  来源: 博客园  发布时间: 2013-02-23 21:22  阅读: 16895 次  推荐: 43   原文链接 [收藏]

      用Visual Studio等IDE写C#的Hello World非常简单,但脱离了IDE你能不能打印出Hello World呢?这不是说工作时脱离IDE,而是学习一下CLR的执行模型.

      Hello World

    1. 新建一个记事本,输入如下代码,另存为HelloWorld.txt。
      using System;
      
      namespace HelloWorld
      {
         class Program
         {
              static void Main(string[] args) {
                  Console.WriteLine("Hello World!");
                  Console.ReadKey();
              }
          }
      }
    2. 打开Visual Studio 2008(2005,2010) 命令提示程序
      image

    3. 切换到HelloWorld.txt的目录
      image

    4. 运行命令:csc /out:Hello.exe HelloWorld.txt
      image

      如无意外,将会编译出Hello.exe,能打印出Hello World。

      CLR执行模型-编译期

      CLR程序的执行过程大致分为两步,编译期和运行期,编译期过程大致如下图:

    image

      其中编译期逻辑上也可分为两步:

    1. CLR(C#)编译器接受源代码文件,并编译为托管模块。托管模块包括IL代码、元数据、CLR头等组成部分。上面的例子中就是将HelloWorld.txt编译成托管模块。
    2. 一般程序集都会包含很多源代码文件(这里只有HelloWorld.txt)和资源文件,第二步就是把各个源代码文件和资源文件对应编译结果合并成程序集。

      执行上面两步就可以得到一个XX.dll或XX.exe的程序集,就像上面的Hello.exe。

      编译器如何知道要编译成托管模块还是资源文件?其实是必须明确告诉编译器每个文件的怎么编译,这个对应Visual Studio的文件属性的生成操作.

      右击任何Visual Studio解决资源方案的文件–>属性–>生成操作:

    image

      指定Class1为嵌入的资源,用ILSpy查看会发现只是把Class1嵌入到程序集中,名称为:命名空间.文件名:

    image

      你甚至可以将一张图片设为编译让编译器试图去编译它,不过会报错。

      运行期

      上面生成了程序集,程序集内的是IL代码,它还不是可运行的代码。IL是与CPU无关的机器语言,直到程序集被调用,才会由JIT(Just-in-Time,实时)编译器编译为本机代码(CPU指令)。在运行时,CLR执行如下步骤:

    1. 检查程序集的安全特性;
    2. 在内存中分配空间;
    3. 把程序集中的可执行代码发送给JIT编译器,把其中一部分编译成本机代码(CPU指令)。

      程序集的可执行代码在需要的时候由JIT编译器编译,然后本机代码(CPU指令)就被缓存以备后来的程序中执行。一旦应用程序终止,编译好的本机代码也会被丢弃。

      例如如果将上面的代码改为:

    static void Main(string[] args) {
        Console.WriteLine("Hello");
        Console.WriteLine("World!");
        Console.ReadKey();
    }

      第一个WriteLine需要先JIT编译,再执行。而由于已编译WriteLine的代码,所以第二个WriteLine会直接执行内存块中的代码,跳过JIT编译。

      由于分配内存、JIT编译过程等,所以程序会在第一次运行时造成一些性能损失,写ASP.NET时这种感觉特变明显,按了F5会等很久才会显示首页。

      下面模拟感受这个过程。用一大堆类延长内存分配的时间,参考这个文件HelloWorld.cs(博客园不支持txt格式):

    image

      再次运行命令:csc /out:Hello.exe HelloWorld.txt,得到Hello.exe,执行时发现有一定的延迟才会打印出Hello World。

      生成本机代码

      使用.NET提供的NGen.exe,可以将IL代码编译成本机代码,可以解决上面的问题。NGen.exe有两个作用:

    1. 加快应用程序的启动速度。因为代码已编译为本机代码,运行时不需要再花时间编译。
    2. 减少应用程序的程序集。如果一个程序集会同时加载多个进程,NGen.exe会将IL编译成本机代码,并保存到一个单独的文件中。这样就可以通过”内存映射”的方式,同时映射到多个进程中,使代码共享,避免每个进程一份代码。

      再次运行 Visual Studio 2008(2005,2010) 命令提示程序

      运行如下命令:ngen install Hello.exe:

    image
      命令完成(在我的机器大概要10秒左右,到能再次输入命令才完成)后,运行Hello.exe会发现马上就能打印出Hello World,没有任何延迟。

      参考:

      CLR via C# 第3版

      C#图解教程

  • OWIN初探(转)

    作者: 张志敏  发布时间: 2014-11-24 11:45  阅读: 21325 次  推荐: 22   原文链接 [收藏]

      什么是 OWIN ?

    OWIN 的全称是 “Open Web Interface for .NET”, OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一套标准的接口, 其目的是为了实现服务器与应用之间的解耦, 鼓励为 .NET Web 应用开发简单模块。

      OWIN 是一个开源开放的标准, 有助于建设 .NET 开发的开源生态环境,OWIN 定义了如下几个概念:

    • 服务器 (Server)

      HTTP 服务器直接与客户端交互, 并用 OWIN 语义处理请求,服务器需要一个适配层将客户请求转换 成 OWIN 语义。 支持 OWIN 的服务器有 Katana 和 Nowin 。

    • Web 框架 (Web Framework)

      构建在 OWIN 之上的自包含的独立组件, 向 Web 应用提供可用的对象模型或者接口。 Web 框架可 能需要一个适配层来转换 OWIN 语义。 支持 OWIN 的 Web 框架有:

    • Web 应用 (Web Application)

      一个特定的 Web 应用, 通常构建在 Web 框架之上, 使用 OWIN 兼容的服务器运行。

    • 中间件 (Middleware)

      特定目的的服务器和应用之间的可插拔组件, 可以监视、 路由、 修改请求与响应。

    • 宿主 (Host)

      应用与服务器所在的进程, 主要负责应用的启动, 有些服务器自身也是宿主, 比如 Nowin 。

      为什么使用 OWIN

      正如上面所说, OWIN 定义了 .NET Web 服务器与 .NET Web 应用之间的标准接口, 将应用与服务器 解耦, 使得便携式 .NET Web 应用以及跨平台的愿望成为现实, 标准的 OWIN 应用可以在任何 OWIN 兼容的服务器上运行, 不再依赖与 Windows 和 IIS 。

      怎么使用 OWIN

      OWIN 通过 NuGet 包的形式发布, 获取和使用都非常方便。 下面就先建立一个最简单的 OWIN 应用:

    1. 打开 Xamarin Studio, 新建一个 C# 命令行程序, 如下图所示:

      OWIN Hello

    2. 然后打开项目属性, 确认目标框架设置为 Mono/.NET 4.5 , 如下图所示:

    3. 向项目中添加如下几个 NuGet 包:

      • Owin
      • Microsoft.Owin
      • Microsoft.Owin.Hosting
      • Microsoft.Owin.Host.HttpListener
    4. 添加一个 OWIN Startup 类, 代码如下:

      public class Startup {
      
          public void Configuration(IAppBuilder appBuilder) {
              appBuilder.Run(HandleRequest);
          }
      
          static Task HandleRequest(IOwinContext context) {
              context.Response.ContentType = "text/plain";
              return context.Response.WriteAsync("Hello, world!");
          }
      }

      OWIN 约定的处理请求的代理类型是:

      Func<IOWinContext, Task> handler

      对应上面 Startup 类的 HandleRequest 方法, 所以上面的 Startup 类就定义了一个最简单的 OWIN 应用, 向客户端输出 Hello, World!

    5. 在自动生成的 Program.cs 文件中的 Main 方法中添加如下代码, 来启动 OWIN 应用:

      class MainClass {
          public static void Main(string[] args) {
              var url = "http://localhost:8080/";
              var startOpts = new StartOptions(url) {
      
              };
              using (WebApp.Start<Startup>(startOpts)) {
                  Console.WriteLine("Server run at " + url + " , press Enter to exit.");
                  Console.ReadLine();
              }
          }
      }
    6. 现在开始运行程序, 命令行显示如下:

      打开浏览器, 访问 http://localhost:8080/ , 得到的响应如下:

      OWIN Hello

      到目前为止, 没有 Windows , 更没有 IIS , OWIN 应用就能正常运行了。

  • .NET技术+25台服务器怎样支撑世界第54大网站(转)

    StackOverflow 是一个 IT 技术问答网站,用户可以在网站上提交和回答问题。当下的 StackOverflow 已拥有 400 万个用户,4000 万个回答,月 PV5.6 亿,世界排行第 54。然而值得关注的是,支撑他们网站的全部服务器只有 25 台,并且都保持着非常低的资源使用率,这是一场高有效性、负载均衡、缓存、数据库、搜索及高效代码上的较量。近日,High Scalability 创始人 Todd Hoff 根据 Marco Cecconi 的演讲视频“ The architecture of StackOverflow”以及 Nick Craver 的博文“ What it takes to run Stack Overflow”总结了 StackOverflow 的成功原因。

    image

      意料之中,也是意料之外,Stack Overflow 仍然重度使用着微软的产品。他们认为既然微软的基础设施可以满足需求,又足够便宜,那么没有什么理由去做根本上的改变。而在需要的地方,他们同样使用了 Linux。究其根本,一切都是为了性能。

      另一个值得关注的地方是,Stack Overflow 仍然使用着纵向扩展策略,没有使用云。他们使用了 384GB 的内存和 2TB 的 SSD 来支撑 SQL Servers,如果使用 AWS 的话,花费可想而知。没有使用云的另一个原因是 Stack Overflow 认为云会一定程度上的降低性能,同时也会给优化和排查系统问题增加难度。此外,他们的架构也并不需要横向扩展。峰值期间是横向扩展的杀手级应用场景,然而他们有着丰富的系统调整经验去应对。该公司仍然坚持着 Jeff Atwood 的名言——硬件永远比程序员便宜。

      Marco Ceccon 曾提到,在谈及系统时,有一件事情必须首先弄明白——需要解决问题的类型。首先,从简单方面着手,StackExchange 究竟是用来做什么的——首先是一些主题,然后围绕这些主题建立社区,最后就形成了这个令人敬佩的问答网站。

      其次则是规模相关。StackExchange 在飞速增长,需要处理大量的数据传输,那么这些都是如何完成的,特别是只使用了 25 台服务器,下面一起追根揭底:

    状态

    • StackExchange 拥有 110 个站点,以每个月 3 到 4 个的速度增长。
    • 400 万用户
    • 800 万问题
    • 4000 万答案
    • 世界排名 54 位
    • 每年增长 100%
    • 月 PV 5.6 亿万
    • 大多数工作日期间峰值为 2600 到 3000 请求每秒,作为一个编程相关网站,一般情况下工作日的请求都会高于周末
    • 25 台服务器
    • SSD 中储存了 2TB 的 SQL 数据
    • 每个 web server 都配置了 2 个 320G 的 SSD,使用 RAID 1
    • 每个 ElasticSearch 主机都配备了 300GB 的机械硬盘,同时也使用了 SSD
    • Stack Overflow 的读写比是 40:60
    • DB Server 的平均 CPU 利用率是 10%
    • 11 个 web server,使用 IIS
    • 2 个负载均衡器,1 个活跃,使用 HAProxy
    • 4 个活跃的数据库节点,使用 MS SQL
    • 3 台实现了 tag engine 的应用程序服务器,所有搜索都通过 tag
    • 3 台服务器通过 ElasticSearch 做搜索
    • 2 台使用了 Redis 的服务器支撑分布式缓存和消息
    • 2 台 Networks(Nexus 5596 + Fabric Extenders)
    • 2 Cisco 5525-X ASAs 
    • 2 Cisco 3945 Routers
    • 主要服务 Stack Exchange API 的 2 个只读 SQL Servers
    • VM 用于部署、域控制器、监控、运维数据库等场合

    平台

    • ElasticSearch
    • Redis
    • HAProxy
    • MS SQL
    • Opserver
    • TeamCity
    • Jil——Fast .NET JSON Serializer,建立在 Sigil 之上
    • Dapper——微型的 ORM

    UI

    • UI 拥有一个信息收件箱,用于新徽章获得、用户发送信息、重大事件发生时的信息收取,使用 WebSockets 实现,并通过 Redis 支撑。
    • 搜索箱通过 ElasticSearch 实现,使用了一个 REST 接口。
    • 因为用户提出问题的频率很高,因此很难显示最新问题,每秒都会有新的问题产生,从而这里需要开发一个关注用户行为模式的算法,只给用户显示感兴趣的问题。它使用了基于 Tag 的复杂查询,这也是开发独立 Tag Engine 的原因。
    • 服务器端模板用于生成页面。

    服务器

    • 25 台服务器并没有满载,CPU 使用率并不高,单计算 SO(Stack Overflow)只需要 5 台服务器。
    • 数据库服务器资源利用率在 10% 左右,除下执行备份时。
    • 为什么会这么低?因为数据库服务器足足拥有 384GB 内存,同时 web server 的 CPU 利用率也只有 10%-15%。
    • 纵向扩展还没有遇到瓶颈。通常情况下,如此流量使用横向扩展大约需要 100 到 300 台服务器。
    • 简单的系统。基于 .Net,只用了 9 个项目,其他系统可能需要 100 个。之所以使用这么少系统是为了追求极限的编译速度,这点需要从系统开始时就进行规划,每台服务器的编译时间大约是 10 秒。
    • 11 万行代码,对比流量来说非常少。
    • 使用这种极简的方式主要基于几个原因。首先,不需要太多测试,因为 Meta.stackoverflow 本来就是一个问题和 bug 讨论社区。其次,Meta.stackoverflow 还是一个软件的测试网站,如果用户发现问题的话,往往会提出并给予解决方案。
    • 纽约数据中心使用的是 Windows 2012,已经向 2012 R2 升级(Oregon 已经完成了升级),Linux 系统使用的是 Centos 6.4。

    SSD

    • 默认使用的是 Intel 330(Web 层等)
    • Intel 520 用于中间层写入,比如 Elastic Search
    • 数据层使用 Intel 710 和 S3700
    • 系统同时使用了 RAID 1 和 RAID 10(任何4+ 以上的磁盘都使用 RAID 10)。不畏惧故障发生,即使生产环境中使用了上千块 2.5 英寸 SSD,还没碰到过一块失败的情景。每个模型都使用了 1 个以上的备件,多个磁盘发生故障的情景不在考虑之中。
    • ElasticSearch 在 SSD 上表现的异常出色,因为 SO writes/re-indexes 的操作非常频繁。
    • SSD 改变了搜索的使用方式。因为锁的问题,Luncene.net 并不能支撑 SO 的并发负载,因此他们转向了 ElasticSearch。在全 SSD 环境下,并不需要围绕 Binary Reader 建立锁。

    高可用性

    • 异地备份——主数据中心位于纽约,备份数据中心在 Oregon。
    • Redis 有两个从节点,SQL 有 2 个备份,Tag Engine 有 3 个节点,elastic 有 3 个节点,冗余一切,并在两个数据中心同时存在。
    • Nginx 是用于 SSL,终止 SSL 时转换使用 HAProxy。
    • 并不是主从所有,一些临时的数据只会放到缓存中
    • 所有 HTTP 流量发送只占总流量的 77%,还存在 Oregon 数据中心的备份及一些其他的 VPN 流量。这些流量主要由 SQL 和 Redis 备份产生。

    数据库

    • MS SQL Server
    • Stack Exchange 为每个网站都设置了数据库,因此 Stack Overflow 有一个、Server Fault 有一个,以此类推。
    • 在纽约的主数据中心,每个集群通常都使用 1 主和 1 只读备份的配置,同时还会在 Oregon 数据中心也设置一个备份。如果是运行的是 Oregon 集群,那么两个在纽约数据中心的备份都会是只读和同步的。
    • 为其他内容准备的数据库。这里还存在一个“网络范围”的数据库,用于储存登陆凭证和聚合数据(大部分是 stackexchange.com 用户文件或者 API)。
    • Careers Stack Overflow、stackexchange.com 和 Area 51 等都拥有自己独立的数据库模式。
    • 模式的变化需要同时提供给所有站点的数据库,它们需要向下兼容,举个例子,如果需要重命名一个列,那么将非常麻烦,这里需要进行多个操作:增加一个新列,添加作用在两个列上的代码,给新列写数据,改变代码让新列有效,移除旧列。
    • 并不需要分片,所有事情通过索引来解决,而且数据体积也没那么大。如果有 filtered indexes 需求,那么为什么不更高效的进行?常见模式只在 DeletionDate = Null 上做索引,其他则通过为枚举指定类型。每项 votes 都设置了 1 个表,比如一张表给 post votes,1 张表给 comment votes。大部分的页面都可以实时渲染,只为匿名用户缓存,因此,不存在缓存更新,只有重查询。
    • Scores 是非规范化的,因此需要经常查询。它只包含 IDs 和 dates,post votes 表格当下大约有 56454478 行,使用索引,大部分的查询都可以在数毫秒内完成。
    • Tag Engine 是完全独立的,这就意味着核心功能并不依赖任何外部应用程序。它是一个巨大的内存结构数组结构,专为 SO 用例优化,并为重负载组合进行预计算。Tag Engine 是个简单的 windows 服务,冗余的运行在多个主机上。CPU 使用率基本上保持在2-5%,3 个主机专门用于冗余,不负责任何负载。如果所有主机同时发生故障,网络服务器将把 Tag Engine 加载到内存中持续运行。
    • 关于 Dapper 无编译器校验查询与传统 ORM 的对比。使用编译器有很多好处,但在运行时仍然会存在 fundamental disconnect 问题。同时更重要的是,由于生成 nasty SQL,通常情况还需要去寻找原始代码,而 Query Hint 和 parameterization 控制等能力的缺乏更让查询优化变得复杂。

    编码

    • 流程
    • 大部分程序员都是远程工作,自己选择编码地点
    • 编译非常快
    • 然后运行少量的测试
    • 一旦编译成功,代码即转移至开发交付准备服务器
    • 通过功能开关隐藏新功能
    • 在相同硬件上作为其他站点测试运行
    • 然后转移至 Meta.stackoverflow 测试,每天有上千个程序员在使用,一个很好的测试环境
    • 如果通过则上线,在更广大的社区进行测试
    • 大量使用静态类和方法,为了更简单及更好的性能
    • 编码过程非常简单,因为复杂的部分被打包到库里,这些库被开源和维护。.Net 项目数量很低,因为使用了社区共享的部分代码。
    • 开发者同时使用 2 到 3 个显示器,多个屏幕可以显著提高生产效率。

    缓存

    • 缓存一切
    • 5 个等级的缓存
    • 1 级是网络级缓存,缓存在浏览器、CDN 以及代理服务器中。
    • 2 级由 .Net 框架 HttpRuntime.Cache 完成,在每台服务器的内存中。
    • 3 级 Redis,分布式内存键值存储,在多个支撑同一个站点的服务器上共享缓存项。
    • 4 级 SQL Server Cache,整个数据库,所有数据都被放到内存中。
    • 5 级 SSD。通常只在 SQL Server 预热后才生效。
    • 举个例子,每个帮助页面都进行了缓存,访问一个页面的代码非常简单:
    • 使用了静态的方法和类。从 OOP 角度来看确实很糟,但是非常快并有利于简洁编码。
    • 缓存由 Redis 和 Dapper 支撑,一个微型 ORM
    • 为了解决垃圾收集问题,模板中 1 个类只使用 1 个副本,被建立和保存在缓存中。监测一切,包括 GC 操。据统计显示,间接层增加 GC 压力达到了某个程度时会显著的降低性能。
    • CDN Hit 。鉴于查询字符串基于文件内容进行哈希,只在有新建立时才会被再次取出。每天 3000 万到 5000 万 Hit,带宽大约为 300GB 到 600GB。
    • CDN 不是用来应对 CPU 或I/O负载,而是帮助用户更快的获得答案

    部署

    • 每天 5 次部署,不去建立过大的应用。主要因为
    • 可以直接的监视性能
    • 尽可能最小化建立,可以工作才是重点
    • 产品建立后再通过强大的脚本拷贝到各个网页层,每个服务器的步骤是:
    • 通过 POST 通知 HAProxy 下架某台服务器
    • 延迟 IIS 结束现有请求(大约 5 秒)
    • 停止网站(通过同一个 PSSession 结束所有下游)
    • Robocopy 文件
    • 开启网站
    • 通过另一个 POST 做 HAProxy Re-enable
    • 几乎所有部署都是通过 puppet 或 DSC,升级通常只是大幅度调整 RAID 阵列并通过 PXE boot 安装,这样做非常快速。

    协作

    • 团队
    • SRE (System Reliability Engineering):5 人
    • Core Dev(Q&A site)6-7 人
    • Core Dev Mobile:6 人
    • Careers 团队专门负责 SO Careers 产品开发:7 人
    • Devops 和开发者结合的非常紧密
    • 团队间变化很大
    • 大部分员工远程工作
    • 办公室主要用于销售,Denver 和 London 除外
    • 一切平等,些许偏向纽约工作者,因为面对面有助于工作交流,但是在线工作影响也并不大
    • 对比可以在同一个办公室办公,他们更偏向热爱产品及有才华的工程师,他们可以很好的衡量利弊
    • 许多人因为家庭而选择远程工作,纽约是不错,但是生活并不宽松
    • 办公室设立在曼哈顿,那是个人才的诞生地。数据中心不能太偏,因为经常会涉及升级
    • 打造一个强大团队,偏爱极客。早期的微软就聚集了大量极客,因此他们征服了整个世界
    • Stack Overflow 社区也是个招聘的地点,他们在那寻找热爱编码、乐于助人及热爱交流的人才。

    编制预算

    • 预算是项目的基础。钱只花在为新项目建立基础设施上,如此低利用率的 web server 还是 3 年前数据中心建立时购入。

    测试

    • 快速迭代和遗弃
    • 许多测试都是发布队伍完成的。开发拥有一个同样的 SQL 服务器,并且运行在相同的 Web 层,因此性能测试并不会糟糕。
    • 非常少的测试。Stack Overflow 并没有进行太多的单元测试,因为他们使用了大量的静态代码,还有一个非常活跃的社区。
    • 基础设施改变。鉴于所有东西都有双份,所以每个旧配置都有备份,并使用了一个快速故障恢复机制。比如,keepalived 可以在负载均衡器中快速回退。
    • 对比定期维护,他们更愿意依赖冗余系统。SQL 备份用一个专门的服务器进行测试,只为了可以重存储。计划做每两个月一次的全数据中心故障恢复,或者使用完全只读的第二数据中心。
    • 每次新功能发布都做单元测试、集成测试盒 UI 测试,这就意味着可以预知输入的产品功能测试后就会推送到孵化网站,即 meta.stackexchange(原 meta.stackoverflow)。

    监视/日志

    • 当下正在考虑使用 http://logstash.net/做日志管理,目前使用了一个专门的服务将 syslog UDP 传输到 SQL 数据库中。网页中为计时添加 header,这样就可以通过 HAProxy 来捕获并且融合到 syslog 传输中。
    • Opserver 和 Realog 用于显示测量结果。Realog 是一个日志展示系统,由 Kyle Brandt 和 Matt Jibson 使用 Go 建立。
    • 日志通过 HAProxy 负载均衡器借助 syslog 完成,而不是 IIS,因为其功能比 IIS 更丰富。

    关于云

    • 还是老生常谈,硬件永远比开发者和有效率的代码便宜。基于木桶效应,速度肯定受限于某个短板,现有的云服务基本上都存在容量和性能限制。
    • 如果从开始就使用云来建设 SO 说不定也会达到现在的水准。但毫无疑问的是,如果达到同样的性能,使用云的成本将远远高于自建数据中心。

    性能至上

    • StackOverflow 是个重度的性能控,主页加载的时间永远控制在 50 毫秒内,当下的响应时间是 28 毫秒。
    • 程序员热衷于降低页面加载时间以及提高用户体验。
    • 每个独立的网络提交都予以计时和记录,这种计量可以弄清楚提升性能需要修改的地方。
    • 如此低资源利用率的主要原因就是高效的代码。web server 的 CPU 平均利用率在5% 到 15% 之间,内存使用为 15.5 GB,网络传输在 20 Mb/s到 40 Mb/s。SQL 服务器的 CPU 使用率在5% 到 10% 之间,内存使用是 365GB,网络传输为 100 Mb/s到 200 Mb/s。这可以带来 3 个好处:给升级留下很大的空间;在严重错误发生时可以保持服务可用;在需要时可以快速回档。

    学到的知识

    1. 为什么使用 MS 产品的同时还使用 Redis?什么好用用什么,不要做无必要的系统之争,比如 C# 在 Windows 机器上运行最好,我们使用 IIS;Redis 在*nix 机器上可以得到充分发挥,我们使用*nix。

    2. Overkill 即策略。平常的利用率并不能代表什么,当某些特定的事情发生时,比如备份、重建等完全可以将资源使用拉满。

    3. 坚固的 SSD。所有数据库都建立在 SSD 之上,这样可以获得 0 延时。

    4. 了解你的读写负载。

    5. 高效的代码意味着更少的主机。只有新项目上线时才会因为特殊需求增加硬件,通常情况下是添加内存,但在此之外,高效的代码就意味着 0 硬件添加。所以经常只讨论两个问题:为存储增加新的 SSD;为新项目增加硬件。

    6. 不要害怕定制化。SO 在 Tag 上使用复杂查询,因此专门开发了所需的 Tag Engine。

    7. 只做必须做的事情。之所以不需要测试是因为有一个活跃的社区支撑,比如,开发者不用担心出现“Square Wheel”效应,如果开发者可以制作一个更更轻量级的组件,那就替代吧。

    8. 注重硬件知识,比如 IL。一些代码使用 IL 而不是C#。聚焦 SQL 查询计划。使用 web server 的内存转储究竟做了些什么。探索,比如为什么一个 split 会产生 2GB 的垃圾。

    9. 切勿官僚作风。总有一些新的工具是你需要的,比如,一个编辑器,新版本的 Visual Studio,降低提升过程中的一切阻力。

    10. 垃圾回收驱动编程。SO 在减少垃圾回收成本上做了很多努力,跳过类似 TDD 的实践,避免抽象层,使用静态方法。虽然极端,但是确实打造出非常高效的代码。

    11. 高效代码的价值远远超出你想象,它可以让硬件跑的更快,降低资源使用,切记让代码更容易被程序员理解。

    转自:http://kb.cnblogs.com/page/214296/