Linux查看内存使用情况的方法

内容来源于网络

1. /proc/meminfo

查看RAM使用情况最简单的方法是通过/proc/meminfo。这个动态更新的虚拟文件实际上是许多其他内存相关工具(如:free / ps / top)等的组合显示。/proc/meminfo列出了所有你想了解的内存的使用情况。进程的内存使用信息也可以通过/proc/<pid>/statm 和 /proc/<pid>/status 来查看。

1

$ cat /proc/meminfo

点击查看原图

2. atop

atop命令是一个终端环境的监控命令。它显示的是各种系统资源(CPU, memory, network, I/O, kernel)的综合,并且在高负载的情况下进行了彩色标注。

1

$ sudo atop

点击查看原图

3. free

free命令是一个快速查看内存使用情况的方法,它是对 /proc/meminfo 收集到的信息的一个概述。

1

$ free -h

点击查看原图

4. GNOME System Monitor

GNOME System Monitor 是一个显示最近一段时间内的CPU、内存、交换区及网络的使用情况的视图工具。它还提供了一种查看CPU及内存使用情况的方法。

1

$ gnome-system-monitor

点击查看原图

5. htop

htop命令显示了每个进程的内存实时使用率。它提供了所有进程的常驻内存大小、程序总内存大小、共享库大小等的报告。列表可以水平及垂直滚动。

1

$ htop

点击查看原图

6. KDE System Monitor

功能同 4 中介绍的GENOME版本。

1

$ ksysguard

点击查看原图

7. memstat

memstat是一个有效识别executable(s), process(es) and shared libraries使用虚拟内存情况的命令。给定一个进程ID,memstat可以列出这个进程相关的可执行文件、数据和共享库。

1

$ memstat -p <PID>

点击查看原图

8. nmon

nmon是一个基于ncurses的系统基准测试工具,它可以监控CPU、内存、I/O、文件系统及网络资源等的互动模式。对于内存的使用,它可以实时的显示 总/剩余内存、交换空间等信息。

1

$ nmon

点击查看原图


9. ps

ps命令可以实时的显示各个进程的内存使用情况。Reported memory usage information includes
%MEM (percent of physical memory used), VSZ (total amount of virtual
memory used), and RSS (total amount of physical memory used)。你可以使用
“–sort”选项对进程进行排序,例如按RSS进行排序:

1

$ ps aux --sort -rss

点击查看原图

10. smem

smem命令允许你统计基于/proc信息的不同进程和用户的内存使用情况。内存使用情况的分析可以导出图表(如条形图和饼图)。

1

$ sudo smem --pie name -c "pss"

点击查看原图

11. top

top命令提供了实时的运行中的程序的资源使用统计。你可以根据内存的使用和大小来进行排序。

1

$ top

点击查看原图

12. vmstat

vmstat命令显示实时的和平均的统计,覆盖CPU、内存、I/O等内容。例如内存情况,不仅显示物理内存,也统计虚拟内存。

1

$ vmstat -s

发表在 linux | 标签为 , | Linux查看内存使用情况的方法已关闭评论

磁盘性能测试方法

测试随机写IOPS:

fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4k
-size=10G -numjobs=1 -runtime=1000 -group_reporting
-name=/path/testfile

测试随机读IOPS:

fio -direct=1 -iodepth=128 -rw=randread -ioengine=libaio -bs=4k
-size=10G -numjobs=1 -runtime=1000 -group_reporting
-name=/path/testfile

测试写吞吐量:

fio -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=64k
-size=10G -numjobs=1 -runtime=1000 -group_reporting
-name=/path/testfile

测试读吞吐量:

fio -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=64k
-size=10G -numjobs=1 -runtime=1000 -group_reporting
-name=/path/testfile

 

案例:

写:time dd if=/dev/zero of=/mnt/mfs/test2/test500M bs=1024k count=500
读:time dd if=/mnt/mfs/test2/test500M of=/dev/null

1copy写     2copy写     1copy读     2copy读    
1M   0m0.042s 0m0.042s 0m0.017s 0m0.017s
5M 0m0.073s 0m0.079s 0m0.070s 0m0.071s
20M 0m0.250s 0m0.288s 0m0.291s 0m0.376s
50M 0m0.514s 0m0.589s 0m0.896s 0m0.886s
100M 0m0.977s 0m7.497s 0m1.677s 0m1.787s
200M   0m7.910s 0m22.270s 0m2.683s 0m3.129s
500M 0m22.465s 0m51.735s 0m6.559s 0m6.990s
1G 0m52.346s 1m48.056s 0m17.319s 0m17.154s
2G 1m46.224s 3m46.283s 0m41.608s 0m34.435s
10G 9m29.037s 19m26.237s 3m55.222s 3m24.914s

...

发表在 linux | 磁盘性能测试方法已关闭评论

.NET 资源回收

MSDN建议按照下面的模式实现IDisposable接口:

 public class Foo: IDisposable
{
    public void Dispose()
    {
       Dispose(true);
       GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
     {
        if (!m_disposed)
        {
            if (disposing)
            {
               // Release managed resources
            }
 
            // Release unmanaged resources
 
            m_disposed = true;
        }
     }
 
     ~Foo()
     {
        Dispose(false);
     }
 
     private bool m_disposed;
}

CSDN上一位高手的总结

1、Finalize方法(C#中是析构函数,以下称析构函数)是用于释放非托管资源的,而托管资源会由GC自动回收。所以,我们也可以这样来区分 托管和非托管资源。所有会由GC自动回收的资源,就是托管的资源,而不能由GC自动回收的资源,就是非托管资源。在我们的类中直接使用非托管资源的情况很 少,所以基本上不用我们写析构函数。

2、大部分的非托管资源会给系统带来很多负面影响,例如数据库连接不被释放就可能导致连接池中的可用数据库连接用尽。文件不关闭会导致其它进程无法读写这个文件等等。

实现模型:
1、由于大多数的非托管资源都要求可以手动释放,所以,我们应该专门为释放非托管资源公开一个方法。实现IDispose接口的Dispose方法是最好的模型,因为C#支持using语句快,可以在离开语句块时自动调用Dispose方法。

2、虽然可以手动释放非托管资源,我们仍然要在析构函数中释放非托管资源,这样才是安全的应用程序。否则如果因为程序员的疏忽忘记了手动释放非托管资源, 那么就会带来灾难性的后果。所以说在析构函数中释放非托管资源,是一种补救的措施,至少对于大多数类来说是如此。

3、由于析构函数的调用将导致GC对对象回收的效率降低,所以如果已经完成了析构函数该干的事情(例如释放非托管资源),就应当使用SuppressFinalize方法告诉GC不需要再执行某个对象的析构函数。

4、析构函数中只能释放非托管资源而不能对任何托管的对象/资源进行操作。因为你无法预测析构函数的运行时机,所以,当析构函数被执行的时候,也许你进行操作的托管资源已经被释放了。这样将导致严重的后果。

5、(这是一个规则)如果一个类拥有一个实现了IDispose接口类型的成员,并创建(注意是创建,而不是接收,必须是由类自己创建)它的实例对象,则 这个类也应该实现IDispose接口,并在Dispose方法中调用所有实现了IDispose接口的成员的Dispose方法。
只有这样的才能保证所有实现了IDispose接口的类的对象的Dispose方法能够被调用到,确保可以手动释放任何需要释放的资源。

进阶:

在.NET的对象中实际上有两个用于释放资源的函数:Dispose和Finalize。Finalize的目的是用于释放非托管的资源,而Dispose是用于释放所有资源,包括托管的和非托管的。

在这个模式中,void Dispose(bool disposing)函数通过一个disposing参数来区别当前是否是被Dispose()调用。如果是被Dispose()调用,那么需要同时释放 托管和非托管的资源。如果是被~Foo()(也就是C#的Finalize())调用了,那么只需要释放非托管的资源即可。

这是因为,Dispose()函数是被其它代码显式调用并要求释放资源的,而Finalize是被GC调用的。在GC调用的时候Foo所引用的其它 托管对象可能还不需要被销毁,并且即使要销毁,也会由GC来调用。因此在Finalize中只需要释放非托管资源即可。另外一方面,由于在 Dispose()中已经释放了托管和非托管的资源,因此在对象被GC回收时再次调用Finalize是没有必要的,所以在Dispose()中调用 GC.SuppressFinalize(this)避免重复调用Finalize。

然而,即使重复调用Finalize和Dispose也是不存在问题的,因为有变量m_disposed的存在,资源只会被释放一次,多余的调用会被忽略过去。

因此,上面的模式保证了:

1、 Finalize只释放非托管资源;

2、 Dispose释放托管和非托管资源;

3、 重复调用Finalize和Dispose是没有问题的;

4、 Finalize和Dispose共享相同的资源释放策略,因此他们之间也是没有冲突的。

在C#中,这个模式需要显式地实现,其中C#的~Foo()函数代表了Finalize()。而在C++/CLI中,这个模式是自动实现的,C++的类析构函数则是不一样的。

按照C++语义,析构函数在超出作用域,或者delete的时候被调用。在Managed C++(即.NET 1.1中的托管C++)中,析构函数相当于CLR中的Finalize()方法,在垃圾收集的时候由GC调用,因此,调用的时机是不明确的。在.NET 2.0的C++/CLI中,析构函数的语义被修改为等价与Dispose()方法,这就隐含了两件事情:

1、 所有的C++/CLI中的CLR类都实现了接口IDisposable,因此在C#中可以用using关键字来访问这个类的实例。

2、 析构函数不再等价于Finalize()了。

对于第一点,这是一件好事,我认为在语义上Dispose()更加接近于C++析构函数。对于第二点,Microsoft进行了一次扩展,做法是引入了“!”函数,如下所示:

public ref class Foo
{
    public:
    Foo();
    ~Foo(); // destructor
    !Foo(); // finalizer
};

“!”函数(我实在不知道应该怎么称呼它)取代原来Managed C++中的Finalize()被GC调用。MSDN建议,为了减少代码的重复,可以写这样的代码:

~Foo()
{
    //释放托管的资源
    this->!Foo();
}

!Foo()
{
//释放非托管的资源
}

对于上面这个类,实际上C++/CLI生成对应的C#代码是这样的:

 

 public class Foo
{

    private void !Foo()

    {
    // 释放非托管的资源
    }

    private void ~Foo()
    {
         // 释放托管的资源
         !Foo();
     }
    
     public Foo()
     {
     }
    
     public void Dispose()
     {
         Dispose(true);
         GC.SuppressFinalize(this);
     }
    
     protected virtual void Dispose(bool disposing)
     {
         if (disposing)
         {
            ~Foo();
         }
         else
         {
             try
             {
                !Foo();
             }
             finally
             {
                base.Finalize();
             }
         }
     }
    
     protected void Finalize()
     {
        Dispose(false);
     }
}

 

 

由于~Foo()和!Foo()不会被重复调用(至少MS这样认为),因此在这段代码中没有和前面m_disposed相同的变量,但是基本的结构是一样的。


并且,可以看到实际上并不是~Foo()和!Foo()就是Dispose和Finalize,而是C++/CLI编译器生成了两个Dispose 和Finalize函数,并在合适的时候调用它们。C++/CLI其实已经做了很多工作,但是唯一的一个问题就是依赖于用户在~Foo()中调 用!Foo()。

 

他人写的一段小程序(仅拷贝,未验证)

 测试:

 

    public class b : IDisposable
    {
        public int i;
        public b() { Console.WriteLine("ctor"); }
        ~b() { Console.WriteLine("dtor"); }
        public void Dispose()
        {
            Console.WriteLine("Dispose");
            GC.SuppressFinalize(true);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            b objb = new b { i = 2 };
            using (objb)
            {
                Console.WriteLine("using");
            }
            Console.WriteLine("after using");
        }
    }

  输出:

 

ctor
using
Dispose
after using
dtor
Press any key to continue . . .

 

发表在 .net | 标签为 | .NET 资源回收已关闭评论

HttpUtility.UrlEncode

 using System;
using System.IO;

namespace NETCFDevelopersReference
{
    
/// <summary>
    
/// Replacement for HttpUtility.UrlEncode
    
/// </summary>
    public class HttpUtility
    {
        
public static string UrlEncode(string instring)
        {
            StringReader strRdr 
= new StringReader(instring);
            StringWriter strWtr 
= new StringWriter();
            
int charValue = strRdr.Read();
            
while (charValue != -1)
            {
                
if (((charValue >= 48&& (charValue <= 57)) // 0-9
                    ││((charValue >= 65&& (charValue <= 90)) // A-Z
                    ││((charValue >= 97&& (charValue <= 122))) // a-z
                    strWtr.Write((char) charValue);
                
else if (charValue == 32)    // Space
                    strWtr.Write('+');
                
else 
                    strWtr.Write(
"%{0:x2}", charValue);

                charValue = strRdr.Read();
            }

            return strWtr.ToString();
        }
    }
}


发表在 .net | HttpUtility.UrlEncode已关闭评论

emoji

点击查看原图

一 参考资料

1 Emoji 全编码表:(我参考的这个)
  http://punchdrunker.github.com/iOSEmoji/table_html/flower.html
2 Emoji全编码表
  http://code.iamcal.com/php/emoji/
http://blog.csdn.net/iunion/article/details/7241945

3 iOS5/4 Emoji  兼容性:
  http://stackoverflow.com/questions/7856775/how-to-convert-the-old-emoji-encoding-to-the-latest-encoding-in-ios5
4 MySQL emoji问题
  http://dropblood.com/archives/ios-mysql-emoji
5 Emoji 中文对应表

  http://www.iapps.im/wp-content/uploads/2012/02/emoji-pinyin.png?r=010
6 Emoji 参考
   http://www.unicode.org/emoji/
   对照:
        http://www.unicode.org/Public/emoji/2.0//emoji-data.txt
        http://www.unicode.org/Public/emoji/2.0//emoji-sequences.txt
        http://www.unicode.org/Public/emoji/2.0//emoji-zwj-sequences.txt
7 Emoji UTF-16
        http://punchdrunker.github.io/iOSEmoji/table_html/emoji.json
8 windows 7 补丁

        https://support.microsoft.com/zh-cn/kb/2729094

 9 php
http://ju.outofmemory.cn/entry/46760

http://www.unicode.org/~scherer/emoji4unicode/snapshot/full.html

二 下载资源 

emoji图片和编码表 http://download.csdn.net/detail/qdkfriend/4309051

  包括emoji文件表,emoji数据编码表(Unicode编码,UTF8编码,UTF16编码,SBUnicode编码)

public static function removeEmoji($text) {

    $clean_text = "";

    // Match Emoticons
    $regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
    $clean_text = preg_replace($regexEmoticons, '', $text);

    // Match Miscellaneous Symbols and Pictographs
    $regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
    $clean_text = preg_replace($regexSymbols, '', $clean_text);

    // Match Transport And Map Symbols
    $regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
    $clean_text = preg_replace($regexTransport, '', $clean_text);

    // Match Miscellaneous Symbols
    $regexMisc = '/[\x{2600}-\x{26FF}]/u';
    $clean_text = preg_replace($regexMisc, '', $clean_text);

    // Match Dingbats
    $regexDingbats = '/[\x{2700}-\x{27BF}]/u';
    $clean_text = preg_replace($regexDingbats, '', $clean_text);

    return $clean_text;
}

 

static string EmojiToHex(string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                return content;
            }

            //http://punchdrunker.github.io/iOSEmoji/table_html/emoji.json
            var regexString = @"\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDEFF]";
            var regex = new System.Text.RegularExpressions.Regex(regexString);
            var contentHex = regex.Replace(content, m =>
            {
                int r;
                string r1, r2;

                r = Convert.ToInt32(m.Value[0]);
                r1 = "0x" + r.ToString("X");

                r = Convert.ToInt32(m.Value[1]);
                r2 = "0x" + r.ToString("X");

                return r1 + r2;
            });

            return contentHex;
        }
        
        static string EmojiFromHex(string hexContent)
        {
            if (string.IsNullOrEmpty(hexContent))
            {
                return hexContent;
            }
            var regexString = @"0x[0-9A-Z]{4}|0x[0-9A-Z]{2}";
            var regex = new System.Text.RegularExpressions.Regex(regexString);
            var content = regex.Replace(hexContent, m =>
            {
                var b = m.Value.Substring(2);
                var b1 = Convert.ToInt32(b, 16);
                var b2 = Convert.ToChar(b1);
                return b2.ToString();
            });

            return content;
        }


 //test
            var c = "";
            c = System.Web.HttpUtility.UrlDecode("%ud83d%ude00中文", Encoding.UTF8);//
            Console.WriteLine(c);


            //var c1 = c.ToCharArray();

            var c1 = EmojiToHex(c);
            Console.WriteLine(c1);

            var c2 = EmojiFromHex(c1);
            Console.WriteLine(c2);

            return;

发表在 technologys | 标签为 | emoji已关闭评论

APNS

1、实现provider向APNS推送消息

在通过provider向APNS发送消息之前,我们首先需要了解需要发送的格式,APNS的信息结构包如下图:
点击查看原图

上图显示的这个消息体就是我们的服务器(Provider)发送给APNS服务器的消息结构,APNS验证这个结构正确并提取其中的信息后,再将消息推送到指定的设备。这个结构体包括七个部分:

第一个部分是命令标示符;

第二部分是一个表示这个通知的一个表示位,如果apns不能解释该通知,就返回一个错误包;

第三部分是一个以秒标识的时间值,它标识通知是否有效,标识的通知时间与UNIX之差与当前时间与UNIX时间之差,如果大于零,APNS最少通知一次,如果小于同于零APNS不在存储通知(网络字节顺序)。

第四个部分是我们的device_token的长度,

第五部分是我们的device_token字符串,

第六部分是推送消息体(Payload)的长度,

最后一部分也就是真正的消息内容了,里面包含了推送消息的基本信息,比如消息内容,应用Icon右上角显示多少数字以及推送消息到达时所播放的声音等。

接下来我们拆解看一下Payload(消息体)的结构:

点击查看原图

这其实就是个JSON结构体,alert标签的内容就是会显示在用户手机上的推送信息,badge显示的数量(注意是整型)是会在应用Icon右上角显示的数量,提示有多少条未读消息等,sound就是当推送信息送达是手机播放的声音,传defalut就标明使用系统默认声音,如果传比如“beep.wav”就会播放在我们应用工程目录下名称为beep.wav的音频文件,比如当手机锁屏时QQ在后台收到新消息时的滴滴声。

provider通过APNS提供的接口,通过Socket进行异步通信,

在Production环境下面通过gateway.push.apple.com,端口:2195

在Development环境下通过gateway.sandbox.push.apple.com 端口:2195

Provider可以建立多个与APNs的连接。每个都得用TLS(or SSL)来建立安全通道,需要用到SSL证书(就是上面提到的provider连接APNs要用到的SSL证书)。

发送消息的二进制接口和消息的数据包格式

消息须是网络字节顺序(即大尾顺序),消息里面的payload部分不可以超过256字节,且不得以'\0'结尾。

有这么一种情况,当我们将应用从设备卸载后,推送的消息改如何处理呢。我们知道,当我们将应用从设备卸载后,我们是收不到Provider给我们推送的消息的,但是,如何让APNS和Provider都知道不去向这台卸载了应用的设备推送消息呢?针对这个问题,苹果也已经帮我们解决了,那就是Feedback
service。他是APNS的一部分,APNS会持续的更新Feedback service的列表,当我们的Provider将信息发给APNS推送到我们的设备时,如果这时设备无法将消息推送到指定的应用,就会向APNS服务器报告一个反馈信息,而这个信息就记录在feedback service中。按照这种方式,Provider应该定时的去检测Feedback service的列表,然后删除在自己数据库中记录的存在于反馈列表中的device_token,从而不再向这些设备发送推送信息。连接Feedback service的过程同样使用Socket的方式,连接上后,直接接收由APNS传输给我们的反馈列表,传输完成后断开连接,然后我们根据这个最新的反馈列表在更新我们自己的数据库,删除那些不再需要推送信息的设备的device_token。从Feedback
service读取的数据结构如下:
点击查看原图

结构中包含三个部分,第一部分是一个时间戳,记录的是设备失效后的时间信息,第二个部分是device_token的长度,第三部分就是失效的device_token,我们所要获取的就是第三部分,跟我们的数据库进行对比后,删除对应的device_token,下次不再向这些设备发送推送信息。

The Feedback Service

feedback service包含了这样的列表:某iOS应用程序对应的"设备"("设备"用二进制格式的设备token来标识)。--这些设备是由于各种原因而不能接收APNs发来的消息。

Provider应该定期查询这个列表,并且作出对应处理,如:停止向这些的设备发送消息。

provider访问feedback server通过一个与发送消息类似的二进制接口。

Production环境通过feedback.push.apple.com:2196来建立连接,Development通过feedback.sandbox.push.apple.com:2196。

feedback service和发送消息是不同的服务接口(但都属于APNs),他的连接方式和发送消息是一样的。也要通过证书建立SSL连接,连接后你不需要发送任何命令,直接开始读取流一直读完为止,然后provider要解析读到的数据。

数据是由多个这样的格式组成的:

| 四字节时间 | 2字节的token 长度 | 32字节的设备token |

关 于"四字节时间":Provider需要判断对应设备的这个iOS应用程序有没有在该时间之后重新像provider发送注册推送消息所获得的设备 token。如果没有,就认为该设备失效了,需停止向该设备发送消息。如果有,那就是这个设备失效过,但是现在又有效了,只是feedback service还没来得及刷新列表。

 

简单通知报文

点击查看原图

 

最前面1个字节是命令类型,2-3字节是DeviceToken的长度,后面是DeviceToken的具体值,后面是消息的长度和消息的具体内容。发完消息后,在关闭Socket前还可以查看错误的响应,以便确认消息是否成功地发给APNS,错误响应的报文如下:

点击查看原图

命令为8的表示是错误响应的报文,Status是错误码,Identifier是用于定位具体的哪条推送消息,这个是增强型通知里的传入的值,首先看下苹果都有哪些返回错误码:

点击查看原图

 

增强型通知报文(传入Identifier):

点击查看原图

 

Figure 5-1  Notification format

The first byte in the notification format is a command value of 1. The remaining fields are as follows:

    Identifier—An arbitrary value that identifies this notification. This same identifier is returned in a error-response packet if APNs cannot interpret a notification.

    Expiry—A fixed UNIX epoch date expressed in seconds (UTC) that identifies when the notification is no longer valid and can be discarded. The expiry value uses network byte order (big endian). If the expiry value is positive, APNs tries to deliver the notification at least once. Specify zero (or a value less than zero) to request that APNs not store the notification at all.

    Token length—The length of the device token in network order (that is, big endian)

    Device token—The device token in binary form.

    Payload length—The length of the payload in network order (that is, big endian). The payload must not exceed 256 bytes and must not be null-terminated.

 

批量发送

应使用长连接,一次连接发送多条数据

以下部份内容摘自: http://blog.csdn.net/tlq1988/article/details/9612237

 $pass = ''; // $pass是你在建立证书的时候输入的密码
$ctx = stream_context_create();
// apns.pem就是你的证书的路径了,最好写绝对路径
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if(!$fp) {
    print "Failed to connect $err $errstr";
    exit();
} else {
    print "Connection OK\n";
}
$body = array('aps' => array('badge' => 1));
for($i = 0; $i <= 10000; $i++) {
    $deviceToken = md5(time() . rand(0, 9999999)) . md5(time() . rand(0, 9999999)); // 模拟一个Device Token
    $body['aps']['alert'] = md5(time() . rand(0, 9999999)); // 随便模拟点数据
    $payload = json_encode($body);
    // 这里是简单的消息结构,如果想多发几个但是不要返回错误,可以用这个
    /*
    $msg = chr(0) . pack("n", 32)
        . pack('H*', str_replace(' ', '', $deviceToken))
        . pack("n", strlen($payload)) . $payload;
    */
    // 这个是增强型消息格式,$i就是Identifier,864000就是Expiry了
    $msg = pack('CNNnH*', self::COMMAND_PUSH, $i, 864000, 32, $deviceToken)
        . pack('n', strlen($payload))
        . $payload;
    print "sending message :" . $payload . "\n";
    fwrite($fp, $msg);
    // 这里是读取错误信息,不要没发一条就读取一次,这样苹果会认为攻击而终止连接
    //fread($fp, 6);
}

Broken Pipe,如果你有过大量的数据推送,并且看下你的错误日志那么Writen Broken Pipe你一定不陌生。这个错误产生的原因通常是当管道读端没有在读,而管道的写端继续有线程在写,就会造成管道中断。可以简单的理解为你在向一个已经关闭的连接写数据就会抛出这个错误。

    由于Broken
Pipe的关系,我们不得不重新和苹果服务器建立连接,这个连接耗时在国内.....(你们懂的3sec+),这个应该是我们推送速度最大的瓶颈了。有很
多开发者也许会认为这个是由于国内的网络环境导致,因为他们习惯的“traceroute
gateway.push.apple.com”一下,然后发现30+的路由跳转然后就会说这个断开是无法避免的。如果你这么想那么你就错了

    我们用大量(10W左右)能保证基本正确的Device Token来做测试,平均一次连接的能写入3W左右的数据,好的情况下能一次写完这10W数据!!!这个测试也就证明平凡出现Broken Pipe不是由于网络原因。既然不是由于网络原因,那么我做个大胆的假设:这个连接是由APNs主动断开的

   
那么假设这个猜想是正确的,那苹果什么时候会断开连接了?解释这个问题,我们又做了一个测试:往这10W的Device
Token里面均匀插入1000个错误的Device
Token。神奇的事情发生了,发送期间平均断开连接900次+。这个实验正好验证了我之前的猜测:产生Broken Pipe是因为APNs服务器主动断开了连接,并且是由于错误的Device Token引起的(或者其他的错误)。苹果的错误类型和代码编号:

Status code

Description

0

No errors encountered

1

Processing error

2

Missing device token

3

Missing topic

4

Missing payload

5

Invalid token size

6

Invalid topic size

7

Invalid payload size

8

Invalid token

10

Shutdown

255

None (unknown)

    我们进一步跟进测试,我们发现一个奇怪的现象,断开连接的时的前一个Token并不是我们所特意设置的错误Token。同时我们也发现消息送达率也变得非常的低(偶尔有设备能收到)。这个很好解释,之前我就有文章提到过(官方也有相应说明)当一次连接先发送一个错误的Token,之后的有效Token的消息是无法送达的(http://blog.csdn.net/hjq_tlq/article/details/8131115),这就导致了错误的Token后面的正确的Token全部没有收到,从而送达率也就明显下降了。

    经过上面的测试,当APNs接收到错误的Token的时候会主动断开连接,但是断开连接之前会有1sec左右的延迟。那么你可以有下面这个例子理解:

        你要发送1000条数据并且第20个Token是错误的

        当此次连接发到第20个Token的时候苹果认为此次连接终止(但是连接并没有断开,只是APNs将抛弃之后的内容),并且不处理此次连接之后的消息

        1sec左右的时间之后苹果主动断开SSL连接,如果你继续忘此连接写数据,你将可以捕捉到Broken Pipe错误

        此时由于1sec左右的延迟,你已经发送到了第123个消息

        此时从20以后直至123的消息将全部没有送达

    太可怕了.....你竟然不知道是从哪一个错了!!!苹果是SB啊!先不要做这样的结论,我们先看一下苹果官方文档所给出的东东:

点击查看原图

  • Identifier—An arbitrary value that identifies this notification. This same identifier is returned in a error-response packet
    if APNs cannot interpret a notification.

  • Expiry—A
    fixed UNIX epoch date expressed in seconds (UTC) that identifies when
    the notification is no longer valid and can be discarded. The expiry
    value
    uses network byte order (big endian). If the expiry value is positive,
    APNs tries to deliver the notification at least once. Specify zero (or a
    value less than zero) to request that APNs not store the notification
    at all.

  • Token length—The length of the device token in network order (that is, big endian)

  • Device token—The device token in binary form.

  • Payload length—The length of the payload in network order (that is, big endian). The payload must not exceed 256 bytes and must not be null-terminated.

  • Payload—The notification payload.

   
PS:这里苹果到是做了件好事,这个消息结构在早些的文档中显示的是5-2 Enhanced Notification
Format,而之前的5-1是Notification
Format。区别在于之前的5-1中的消息结构为简单消息结构,没有Identifier和Expiry字段并且Command为0。现在直接把简单的
消息体结构给去掉了,这样可以强制开发者加上Identifier,从而得到返回值。

   
为了方便我直接把官方文档粘过来了哈:)我们需要注意的是Identifier这个东东。没错,这个就是苹果用来提供的给第三方的4唯一标示,如果鸟语不
是很好的话他后面的那个注释大致就是说:一个消息的唯一标识。如果苹果服务器不能解释这个消息,那么将在错误中返回这个唯一标示。

    可恶的苹果并没有说明这个会有延迟,以及怎么确保我们能收到这个错误。我们现在采用的是每发送100条消息,就检查一下(read)是否有失败的。如果你抓到这个错误,那么果断断开连接,并且重新发送这条错误以后的Token,这样就能保证消息基本能送达。

    哦,顺便说一下如何得到错误反馈,如果你发送的时候加上了Identifier,那么此时你一定有一个和APNs的连接吧(废话,没连接怎么write),那么你只要read就好了,如果有就能读到一个二进制数据:)

    有一个也需要提一下,就是APNs的FeedBack功能也一定要用上,这个能帮助你更好的剔除错误的Token。

    当你的Token基本为正确的时候,如果还有大量的Broken Pipe出现,你可以给我留言,我们一起研究到底哪里出问题了:)

 

附: http://www.oschina.net/translate/http2-protocol-for-apns?cmp

 
其它:

2015年12月17日起,发布 “基于 HTTP/2 的全新 APNs 协议”,iOS 系统以及 OS X 系统,统一将最大
playload 大小提升到4KB。参考文档:Apple Push Notification Service Update 12-17 2015

  新旧 APNs 协议工作示意图对比

点击查看原图

    HTTP / 2
 点击查看原图
  
Version Old / socket connect
 
点击查看原图
参考:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW2

APNS架构图:

点击查看原图

发表在 technologys | APNS已关闭评论

BAT 路径

例子:
@echo off
echo 当前盘符:%~d0
echo 当前盘符和路径:%~dp0
echo 当前盘符和路径的短文件名格式:%~sdp0
echo 当前批处理全路径:%~f0
echo 当前CMD默认目录:%cd%

pause

 

通过批处理取当前目录的上一级目录
@echo off
if %cd%==%cd:~,3% echo 当前目录已经是%cd:~,1%盘的根目录!&goto end
cd..
set "bd=%cd%"
cd..
set "bbd=%cd%"
if "%bbd%"=="%bd%" (echo 上一级目录是: %cd:~,1%盘的根目录!
) else call echo 上一级目录是: "%%bd:%bbd%\=%%"
:end
pause

发表在 windows | 标签为 | BAT 路径已关闭评论

顶级域名注册局列表(Registry Listing)

顶级域名 开始推行 是否赞助 用途 赞助商或运营商 网址
.aero 2001 赞助 航空业
Air-transport industry
Societe Internationale de Telecommunications Aeronautiques SC, (SITA) www.information.aero
.asia 2007 赞助 亚洲地区
From Asia/For Asia
DotAsia Organisation www.registry.asia
.biz 2001 非赞助 商务Businesses NeuLevel www.nic.biz
.cat 2005 赞助 加泰罗尼亚语/文化使用
Catalan linguistic & cultural community
Fundació puntCAT www.domini.cat
.com 1995 非赞助 不限(但开始是针对商业注册人,是commercial的宿写)

Unrestricted (but intended for commercial registrants)

VeriSign, Inc. www.verisign-grs.com
.coop 2001 赞助 合伙机构
Cooperatives
DotCooperation, LLC www.communicate.coop
.edu 1995 赞助 美国教育机构
United States educational institutions
EDUCAUSE www.educause.edu/edudomain
.gov 1995 赞助 美国政府机构
United States government
US General Services Administration www.nic.gov
.info 2001 非赞助 不限
Unrestricted use
Afilias Limited www.afilias.info
.int 1998 非赞助 政府间按照国际条约指定的组织
Organizations established by international treaties between governments
Internet Assigned Numbers Authority www.iana.org/int-dom/int.htm
.jobs 2005 赞助 人力资源管理的国际机构
International community of human resource managers
Employ Media LLC www.employmedia.com
.mil 1995 赞助 美国军队
United States military
US DoD Network Information Center www.nic.mil

.mobi 2005 赞助 移动服务商及用户社区
Mobile content providers and users community
mTLD Top Level Domain, LTD. www.mtld.mobi
.museum 2001 赞助 博物馆
Museums
Museum Domain Management Association, (MuseDoma) www.nic.museum
.name 2001 非赞助 个人
For registration by individuals
Global Name Registry, LTD www.gnr.name
.net 1995 非赞助 不限(但开始针对网络机构 network
Unrestricted (but intended for network providers, etc.)
VeriSign, Inc. www.verisign-grs.com
.org 1995 非赞助 不限(但开始针对非盈利的组织organization
Unrestricted (but intended for organizations that do not fit elsewhere)
Public Interest Registry. Until 31 December 2002, .org was operated by VeriSign Global Registry Services. www.pir.org
.pro 2002 非赞助 会计师、律师、医师等专业人士
Accountants, lawyers, physicians, and other professionals
RegistryPro, LTD www.registrypro.pro
.tel 2006 赞助 无说明 Telnic Ltd. www.telnic.org
.travel 2005 赞助 旅游           
Travel and tourism community
Tralliance Corporation www.tralliance.travel

 

 

发表在 network | 顶级域名注册局列表(Registry Listing)已关闭评论

msmq,rabbitmq,activemq,zeromq

摘自网络

RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统。

一些概念:

channel:通道,amqp支持一个tcp连接上启用多个mq通信通道,每个通道都可以被作为通信流。

producer:生产者,是消息产生的源头。

exchange:交换机,可以理解为具有路由表的路由规则。

queues:队列,装载消息的缓存容器。

consumer:消费者,连接到队列并取走消息的客户端。

核心思想:在RabbitMQ中,生产者从不直接将消息发送给队列。

事实上,有些生产者甚至不知道消息是否被送到某个队列中去了。生产者只负责将消息送给交换机,而交换机确切地知道什么消息应该送到哪。

bind:绑定,实际上可以理解为交换机的路由规则。每个消息都有一个称为路由键的属性(routing key),就是一个简单的字符串。一个绑定将【交换机,路由键,消息送达队列】三者绑定在一起,形成一条路由规则。

exchange type:交换机类型:

fanout:不处理路由键,转发到所有绑定的队列上

direct:处理路由键,必须完全匹配,即路由键字符串相同才会转发

topic:路由键模式匹配,此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”

网络获取得一些综合的测试结果:

点击查看原图

 

 rabbitmq原型图

点击查看原图

 

 

 

 

发表在 db | 标签为 , , , | msmq,rabbitmq,activemq,zeromq已关闭评论

private ip range

私有IP就是在本地局域网上的IP 与之对应的是公有IP(在互联网上的IP)。
1、私有地址(Private address,也可称为专网地址)属于非注册地址,专门为组织机构内部使用,它是局域网范畴内的,私有IP禁止出现在Internet中,在ISP连接用户的地方,将来自于私有IP的流量全部都会阻止并丢掉。
2、随着私有IP网络的发展,为节省可分配的注册IP地址,有一组IP地址被拿出来专门用于私有IP网络,称为私有IP地址。
3、私有IP地址范围:
A: 10.0.0.0~10.255.255.255 即10.0.0.0/8
B:172.16.0.0~172.31.255.255即172.16.0.0/12
C:192.168.0.0~192.168.255.255 即192.168.0.0/16
4、
这些地址是不会被Internet分配的,它们在Internet上也不会被路由,虽然它们不能直接和Internet网连接,但通过技术手段仍旧可以和

Internet通讯(NAT技术)。可以根据需要来选择适当的地址类,在内部局域网中将这些地址像公用IP地址一样地使用。在Internet上,有些
不需要与 Internet通讯的设备,如打印机、可管理集线器等也可以使用这些地址,以节省IP地址资源。

发表在 network | 标签为 | private ip range已关闭评论

load average

CPU利用率与Load Average的区别?

CPU利用率,是对一个时间段内CPU使用状况的统计,通过这个指标可以看出在某一个时间段内CPU被占用的情况,如果CPU被占用时间很高,那么就需要考虑CPU是否已经处于超负荷运作,长期超负荷运作对于机器本身来说是一种损害,因此必须将CPU的利用率控制在一定的比例下,以保证机器的正常运作。

Load Average CPULoad,它所包含的信息不是CPU的使用率状况,而是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息。

那么CPU利用率与Load Average对于性能测试的意义有什么区别呢?实际上,CPU利用率反映的是CPU被使用的情况,当CPU长期处于被使用而没有得到足够的时间休息间歇,那么对于CPU硬件来说是一种超负荷的运作,需要调整使用频度。而Load Average却从另一个角度来展现对于CPU使用状态的描述,Load Average越高说明对于CPU资源的竞争越激烈,CPU资源比较短缺。对于资源的申请和维护其实也是需要很大的成本,所以在这种高Average Load的情况下CPU资源的长期“热竞争”也是对于硬件的一种损害。

如何评估性能需求中合理的Load Average

一般来说,Load Average是与机器内核数有关的。以一个单核的机器为例,load=0.5表示CPU还有一半的资源可以处理其他的线程请求,load=1表示CPU所有的资源都在处理请求,没有剩余的资源可以利用了,而load=2则表示CPU已经超负荷运作,另外还有一倍的线程正在等待处理。所以,对于单核机器来说,理想状态下,Load Average要小于1。同理,对于双核处理器来说,Load Average要小于2。结论是:多核处理器中,你的Load Average不应该高于处理器核心的总数量。

不同核处理器之间的load值怎样换算?

性能测试中可能遇到这样的问题,你的线上机器是8核的,但是线下性能测试机只有4核的与16核的,那么我用16核机器测试得到的load值是2.6,换算到8核机器上应该是多少呢?

很不幸,没有一个准确的公式可以用来换算。但是我们可以根据load的含义来做一个推断,假如我们在一个双核的机器上测试100个线程并发访问X页面时load2,那么同样的并发线程数请求同样的页面,在一台单核的机器上测试,load会是多少呢?在双核机器上,100线程同时请求时load2,说明2个核都在满负荷运作,且平均每一个核在同时处理50个线程;如果在单核机器上100个线程同时请求,并且假设每一个核还是能同时处理50个线程,那么就会有50个线程在等待,这样看起来CPUload还是2,但事实上,100个线程同时请求CPU时,已经超出了一个CPU可以同时处理的线程的能力,必然会出现线程之间竞争CPU资源的情况,而线程对CPU的“热竞争”会使CPU耗费更多的资源去做线程调度的事情,所以总体效果来看,单核时load值实际会高于2

上面是我自己的推论,网上还没有找到相应的资料验证。假如这种推论是对的,那么16核机器上测试得到的load2.6,在8核机器上测试的话load值肯定高于2.6究竟高多少应该跟CPU本身的性能也是有关的,具体我还不清楚该如何评估。有兴趣的同学可以一起来讨论讨论哦!

--------------------------------------------------------------------------------------

 

1、先使用top看下CPU占用高的进程,找出进程的进程ID(pid);

查看方法:top
2、根据进程ID(pid)查看是进程的那些线程占用CPU高。
查看方法:top -Hp pid
3、使用pstack,查看CPU占用高的线程在干什么。
查看方法:pstack pid
4、根据pstack分析,应该可以看出问题所在

发表在 linux | load average已关闭评论

php timezone

$timezones =
array (
 '(GMT-12:00) International Date Line West' => 'Pacific/Wake',
 '(GMT-11:00) Midway Island' => 'Pacific/Apia',
 '(GMT-11:00) Samoa' => 'Pacific/Apia',
 '(GMT-10:00) Hawaii' => 'Pacific/Honolulu',
 '(GMT-09:00) Alaska' => 'America/Anchorage',
 '(GMT-08:00) Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles',
 '(GMT-07:00) Arizona' => 'America/Phoenix',
 '(GMT-07:00) Chihuahua' => 'America/Chihuahua',
 '(GMT-07:00) La Paz' => 'America/Chihuahua',
 '(GMT-07:00) Mazatlan' => 'America/Chihuahua',
 '(GMT-07:00) Mountain Time (US & Canada)' => 'America/Denver',
 '(GMT-06:00) Central America' => 'America/Managua',
 '(GMT-06:00) Central Time (US & Canada)' => 'America/Chicago',
 '(GMT-06:00) Guadalajara' => 'America/Mexico_City',
 '(GMT-06:00) Mexico City' => 'America/Mexico_City',
 '(GMT-06:00) Monterrey' => 'America/Mexico_City',
 '(GMT-06:00) Saskatchewan' => 'America/Regina',
 '(GMT-05:00) Bogota' => 'America/Bogota',
 '(GMT-05:00) Eastern Time (US & Canada)' => 'America/New_York',
 '(GMT-05:00) Indiana (East)' => 'America/Indiana/Indianapolis',
 '(GMT-05:00) Lima' => 'America/Bogota',
 '(GMT-05:00) Quito' => 'America/Bogota',
 '(GMT-04:00) Atlantic Time (Canada)' => 'America/Halifax',
 '(GMT-04:00) Caracas' => 'America/Caracas',
 '(GMT-04:00) La Paz' => 'America/Caracas',
 '(GMT-04:00) Santiago' => 'America/Santiago',
 '(GMT-03:30) Newfoundland' => 'America/St_Johns',
 '(GMT-03:00) Brasilia' => 'America/Sao_Paulo',
 '(GMT-03:00) Buenos Aires' => 'America/Argentina/Buenos_Aires',
 '(GMT-03:00) Georgetown' => 'America/Argentina/Buenos_Aires',
 '(GMT-03:00) Greenland' => 'America/Godthab',
 '(GMT-02:00) Mid-Atlantic' => 'America/Noronha',
 '(GMT-01:00) Azores' => 'Atlantic/Azores',
 '(GMT-01:00) Cape Verde Is.' => 'Atlantic/Cape_Verde',
 '(GMT) Casablanca' => 'Africa/Casablanca',
 '(GMT) Edinburgh' => 'Europe/London',
 '(GMT) Greenwich Mean Time : Dublin' => 'Europe/London',
 '(GMT) Lisbon' => 'Europe/London',
 '(GMT) London' => 'Europe/London',
 '(GMT) Monrovia' => 'Africa/Casablanca',
 '(GMT+01:00) Amsterdam' => 'Europe/Berlin',
 '(GMT+01:00) Belgrade' => 'Europe/Belgrade',
 '(GMT+01:00) Berlin' => 'Europe/Berlin',
 '(GMT+01:00) Bern' => 'Europe/Berlin',
 '(GMT+01:00) Bratislava' => 'Europe/Belgrade',
 '(GMT+01:00) Brussels' => 'Europe/Paris',
 '(GMT+01:00) Budapest' => 'Europe/Belgrade',
 '(GMT+01:00) Copenhagen' => 'Europe/Paris',
 '(GMT+01:00) Ljubljana' => 'Europe/Belgrade',
 '(GMT+01:00) Madrid' => 'Europe/Paris',
 '(GMT+01:00) Paris' => 'Europe/Paris',
 '(GMT+01:00) Prague' => 'Europe/Belgrade',
 '(GMT+01:00) Rome' => 'Europe/Berlin',
 '(GMT+01:00) Sarajevo' => 'Europe/Sarajevo',
 '(GMT+01:00) Skopje' => 'Europe/Sarajevo',
 '(GMT+01:00) Stockholm' => 'Europe/Berlin',
 '(GMT+01:00) Vienna' => 'Europe/Berlin',
 '(GMT+01:00) Warsaw' => 'Europe/Sarajevo',
 '(GMT+01:00) West Central Africa' => 'Africa/Lagos',
 '(GMT+01:00) Zagreb' => 'Europe/Sarajevo',
 '(GMT+02:00) Athens' => 'Europe/Istanbul',
 '(GMT+02:00) Bucharest' => 'Europe/Bucharest',
 '(GMT+02:00) Cairo' => 'Africa/Cairo',
 '(GMT+02:00) Harare' => 'Africa/Johannesburg',
 '(GMT+02:00) Helsinki' => 'Europe/Helsinki',
 '(GMT+02:00) Istanbul' => 'Europe/Istanbul',
 '(GMT+02:00) Jerusalem' => 'Asia/Jerusalem',
 '(GMT+02:00) Kyiv' => 'Europe/Helsinki',
 '(GMT+02:00) Minsk' => 'Europe/Istanbul',
 '(GMT+02:00) Pretoria' => 'Africa/Johannesburg',
 '(GMT+02:00) Riga' => 'Europe/Helsinki',
 '(GMT+02:00) Sofia' => 'Europe/Helsinki',
 '(GMT+02:00) Tallinn' => 'Europe/Helsinki',
 '(GMT+02:00) Vilnius' => 'Europe/Helsinki',
 '(GMT+03:00) Baghdad' => 'Asia/Baghdad',
 '(GMT+03:00) Kuwait' => 'Asia/Riyadh',
 '(GMT+03:00) Moscow' => 'Europe/Moscow',
 '(GMT+03:00) Nairobi' => 'Africa/Nairobi',
 '(GMT+03:00) Riyadh' => 'Asia/Riyadh',
 '(GMT+03:00) St. Petersburg' => 'Europe/Moscow',
 '(GMT+03:00) Volgograd' => 'Europe/Moscow',
 '(GMT+03:30) Tehran' => 'Asia/Tehran',
 '(GMT+04:00) Abu Dhabi' => 'Asia/Muscat',
 '(GMT+04:00) Baku' => 'Asia/Tbilisi',
 '(GMT+04:00) Muscat' => 'Asia/Muscat',
 '(GMT+04:00) Tbilisi' => 'Asia/Tbilisi',
 '(GMT+04:00) Yerevan' => 'Asia/Tbilisi',
 '(GMT+04:30) Kabul' => 'Asia/Kabul',
 '(GMT+05:00) Ekaterinburg' => 'Asia/Yekaterinburg',
 '(GMT+05:00) Islamabad' => 'Asia/Karachi',
 '(GMT+05:00) Karachi' => 'Asia/Karachi',
 '(GMT+05:00) Tashkent' => 'Asia/Karachi',
 '(GMT+05:30) Chennai' => 'Asia/Calcutta',
 '(GMT+05:30) Kolkata' => 'Asia/Calcutta',
 '(GMT+05:30) Mumbai' => 'Asia/Calcutta',
 '(GMT+05:30) New Delhi' => 'Asia/Calcutta',
 '(GMT+05:45) Kathmandu' => 'Asia/Katmandu',
 '(GMT+06:00) Almaty' => 'Asia/Novosibirsk',
 '(GMT+06:00) Astana' => 'Asia/Dhaka',
 '(GMT+06:00) Dhaka' => 'Asia/Dhaka',
 '(GMT+06:00) Novosibirsk' => 'Asia/Novosibirsk',
 '(GMT+06:00) Sri Jayawardenepura' => 'Asia/Colombo',
 '(GMT+06:30) Rangoon' => 'Asia/Rangoon',
 '(GMT+07:00) Bangkok' => 'Asia/Bangkok',
 '(GMT+07:00) Hanoi' => 'Asia/Bangkok',
 '(GMT+07:00) Jakarta' => 'Asia/Bangkok',
 '(GMT+07:00) Krasnoyarsk' => 'Asia/Krasnoyarsk',
 '(GMT+08:00) Beijing' => 'Asia/Hong_Kong',
 '(GMT+08:00) Chongqing' => 'Asia/Hong_Kong',
 '(GMT+08:00) Hong Kong' => 'Asia/Hong_Kong',
 '(GMT+08:00) Irkutsk' => 'Asia/Irkutsk',
 '(GMT+08:00) Kuala Lumpur' => 'Asia/Singapore',
 '(GMT+08:00) Perth' => 'Australia/Perth',
 '(GMT+08:00) Singapore' => 'Asia/Singapore',
 '(GMT+08:00) Taipei' => 'Asia/Taipei',
 '(GMT+08:00) Ulaan Bataar' => 'Asia/Irkutsk',
 '(GMT+08:00) Urumqi' => 'Asia/Hong_Kong',
 '(GMT+09:00) Osaka' => 'Asia/Tokyo',
 '(GMT+09:00) Sapporo' => 'Asia/Tokyo',
 '(GMT+09:00) Seoul' => 'Asia/Seoul',
 '(GMT+09:00) Tokyo' => 'Asia/Tokyo',
 '(GMT+09:00) Yakutsk' => 'Asia/Yakutsk',
 '(GMT+09:30) Adelaide' => 'Australia/Adelaide',
 '(GMT+09:30) Darwin' => 'Australia/Darwin',
 '(GMT+10:00) Brisbane' => 'Australia/Brisbane',
 '(GMT+10:00) Canberra' => 'Australia/Sydney',
 '(GMT+10:00) Guam' => 'Pacific/Guam',
 '(GMT+10:00) Hobart' => 'Australia/Hobart',
 '(GMT+10:00) Melbourne' => 'Australia/Sydney',
 '(GMT+10:00) Port Moresby' => 'Pacific/Guam',
 '(GMT+10:00) Sydney' => 'Australia/Sydney',
 '(GMT+10:00) Vladivostok' => 'Asia/Vladivostok',
 '(GMT+11:00) Magadan' => 'Asia/Magadan',
 '(GMT+11:00) New Caledonia' => 'Asia/Magadan',
 '(GMT+11:00) Solomon Is.' => 'Asia/Magadan',
 '(GMT+12:00) Auckland' => 'Pacific/Auckland',
 '(GMT+12:00) Fiji' => 'Pacific/Fiji',
 '(GMT+12:00) Kamchatka' => 'Pacific/Fiji',
 '(GMT+12:00) Marshall Is.' => 'Pacific/Fiji',
 '(GMT+12:00) Wellington' => 'Pacific/Auckland',
 '(GMT+13:00) Nuku\'alofa' => 'Pacific/Tongatapu',

);

 

windows-time-zone.zip

发表在 php | php timezone已关闭评论

MySQL数据库命名规范及约定

一、【操作规范】
1. 如无备注,则表中的第一个id字段一定是主键且为自动增长;
2. 如无备注,则数值类型的字段请使用UNSIGNED属性;
3. 如无备注,排序字段order_id在程序中默认使用降序排列;
4. 如无备注,所有字段都设置NOT NULL,并设置默认值;
5. 如无备注,所有的布尔值字段,如is_hot、is_deleted,都必须设置一个默认值,并设为0;
6. 所有的数字类型字段,都必须设置一个默认值,并设为0;
7. 针对varchar类型字段的程序处理,请验证用户输入,不要超出其预设的长度;
8. 建表时将数据字典中的字段中文名和属性备注写入数据表的备注中(“PK、自动增长”不用写);
9. 如无说明,建表时一律采用innodb引擎;

二、【常用表名约定】
0. 说明:表前缀用项目名称首字母缩写;所以表名都小写,单词之间用下划线分开,单词都用单数形式
1. user – 用户
2. category – 分类
3. goods – 商品、产品等一切可交易网站的物品都用此命名
4. good_gallery – 物品的相册
5. good_cate – 物品的分类,除了单独作为表名,其他地方分类单词一律用缩写cate
4. attr – 属性
5. article – 文章、新闻、帮助中心等以文章形式出现的,一般都用此命名
6. cart – 购物车
7. feedback – 用户反馈
8. order – 订单
9. site_nav – 包括页头和页尾导航
10. site_config – 系统配置表
11. admin – 后台用户 【RBAC标准表】
12. role – 后台用户角色【RBAC标准表】
13. access – 后台操作权限,相当于action【RBAC标准表】
14. role_admin – 后台用户对应的角色【RBAC标准表】
15. access_role – 后台角色对应的权限【RBAC标准表】
16. 待续

三、【常用列名约定】
1. 表名_id – 通常用作外键命名
2. cid –
特殊的编号,带有元数据,方便关联查询,你可以把它理解成类别(层次)编号。举个例子,产品在分类时,往往需要将其归类到子分类下,相应的字段中也一般只
记录子分类的id,这时若需要知道该产品属于哪个主分类,就需要通过子分类信息再查询到主分类信息,这是比较麻烦的,cid字段就是要解决这个问题。一般
的站点几十个分类肯定是够用了,所以这里假设某一主分类的cid为11,则子分类的cid从1101开始编号,处理时只需截取前两位数值便可知道该产品属
于哪一个主分类了。
3. add_time – 添加时间、上架时间等
4. last_time – 最后操作时间,如登录、修改记录
5. expire_time – 过期时间
6. name – 商品名称、商家名称等,不要跟title混用,title只用于文章标题、职称等
7. price – 价格
8. thumb – 只要是列表页面中的窗口图,一律用此命名
9. image_src – 相册中的图片地址一律用此命名,不要出现各种img,image,img_url,thumb_url等
10. head_thumb – 用户头像, 虽然有点长,一定要遵守。不要出现上述情况
11. image_alt – 相册中图片的alt属性
12. desc – 描述、简介,比如goods_desc,不要出现goods_txt这种
13. details – 详情、文章内容等
14. order_id – 排序
15. telephone – 座机号码
16. mobile – 手机号码
17. phone – 当不区分手机和座机时,请用phone命名
18. address – 地址,单独出现不要用addr缩写,组合出现时需用缩写,比如mac地址,mac_addr
19. zipcode – 邮编
20. region – 地区,大的区域,比如记录杭州市、温州市等
21. area – 区域,小的,比如上城区,江干区等
22. avg_cost – 人均消费
23. 待续

四、【数据表字段设计范例】

分类表(t_category

字段名

列名

类型

属性备注

说明

流水号 id int(10) PK、自动增长
特殊编号 cid varchar(4) 第一个主分类为11、第一个子分类为1101,类推,仅支持二级分类
名称 name varchar(10) 页面中需注明输入不超过10个字
父分类 pid int(10)
统计量 count int(10)
是否热门 is_hot tinyint(1)
首页显示 is_index tinyint(1)
排序 order_id int(10)

发表在 db | 标签为 | MySQL数据库命名规范及约定已关闭评论

LISTENING,ESTABLISHED,TIME_WAIT,CLOSE_WAIT

TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不
会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得
注意的状态有两个:CLOSE_WAIT和TIME_WAIT。 
 
1、LISTENING状态
  FTP服务启动后首先处于侦听(LISTENING)状态。

2、ESTABLISHED状态
  ESTABLISHED的意思是建立连接。表示两台机器正在通信。

3、CLOSE_WAIT

    对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

4、TIME_WAIT

   
我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分
段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情
况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。

    目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

 

来源:http://www.cppblog.com/prayer/archive/2009/04/01/78592.html

 

 

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

TCP协议规定,对于已经建立的连接,
网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大
量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源。在众多TCP状态中,最值得注意的状态有两
个:CLOSE_WAIT和TIME_WAIT。  

TIME_WAIT 

TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。主要是防止最后一个ACK丢失。  由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接

CLOSE_WAIT
CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入
CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多
CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到
FIN的连接socket,会返回0。

为什么需要 TIME_WAIT 状态?
假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认
为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT
状态,因为client可能面 临重发最终ACK的情形。

为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?
如果 TIME_WAIT
状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连
接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么
完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。

 TIME_WAIT 和CLOSE_WAIT状态socket过多

如果服务器出了异常,百分之八九十都是下面两种情况:

1.服务器保持了大量TIME_WAIT状态

2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。

因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直
被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常

 

来源:http://blog.csdn.net/kobejayandy/article/details/17655739

发表在 network | LISTENING,ESTABLISHED,TIME_WAIT,CLOSE_WAIT已关闭评论

ParameterInfo properties, attributes and out ref parameters of the methods

引用: http://stackoverflow.com/questions/15636969/parameterinfo-properties-attributes-and-out-ref-parameters-of-the-methods

Well, I'm confused by the properties of the ParameterInfo class.
Unfortunately documentation is not very clear: examples show how to build methods but don't show how these methods look in C#.

Cane somebody tell more about these properties:

  • DefaultValue
  • HasDefaultValue
  • IsIn
  • IsLcid
  • IsOptional
  • IsOut
  • IsRetval

And which combination leads to what method params.
I made a simple program which gives the following output:

Method name M1 void M1(object param)
IL signature: .method public hidebysig instance void M1(object param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=False
IsRetVal=False

Method name M2 void M2(object param = null)
IL signature .method public hidebysig instance void M2([opt] object param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=True
DefaultValue=null
IsIn=False
IsLcid=False
IsOptional=True
IsOut=False
IsRetVal=False

Method name M3 void M3(out object param)
IL signature .method public hidebysig instance void M3([out] object& param) cil managed
Method parameter description:
Is passed by reference True
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=True
IsRetVal=False

Method name M4 void M4(ref object param)
IL signature .method public hidebysig instance void M4(object& param) cil managed
Method parameter description:
Is passed by reference True
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=False
IsRetVal=False

Method name M5 void M5([In] object param)
IL signature .method public hidebysig instance void M5([in] object param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=False
IsIn=True
IsLcid=False
IsOptional=False
IsOut=False
IsRetVal=False

Method name M6 void M6([Out] object param)
IL signature .method public hidebysig instance void M6([out] object param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=True
IsRetVal=False

Method name M7 void M7([Out] out object param)
IL signature .method public hidebysig instance void M7([out] object& param) cil managed
Method parameter description:
Is passed by reference True
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=True
IsRetVal=False

Method name M8 void M8([DefaultValue(null)] object param)
IL signature .method public hidebysig instance void M8(object param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=False
IsOut=False
IsRetVal=False

Method name M9 void M9([DefaultValue(-10)] int param = 10)
IL signature .method public hidebysig instance void M9([opt] int32 param) cil managed
Method parameter description:
Parameter name param
Is passed by reference False
HasDefaultValue=True
DefaultValue=10
IsIn=False
IsLcid=False
IsOptional=True
IsOut=False
IsRetVal=False

Method name M10 void M10([Optional] int param)
IL signature .method public hidebysig instance void M10([opt] int32 param) cil managed
Method parameter description:
Is passed by reference False
HasDefaultValue=False
IsIn=False
IsLcid=False
IsOptional=True
IsOut=False
IsRetVal=False

I guess In, Out and Optional attributes relate to COM as they are located in System.Runtime.InteropServices namesapce.
But again documentation is quite poor. 🙁

And what is RetVal and where it is used?

发表在 .net | ParameterInfo properties, attributes and out ref parameters of the methods已关闭评论