月度归档:2012 年六月

php中ajax异步阻塞解决

在一个项目中使用php调用pcntl模块实现多进程并发队列任务并通过jquery异步获取后台执行结果,但是在前台ajax轮询后台结果的时候出现阻塞,如图所示:

 

第一个请求是用来启动后台多任务进程deamon的ajax请求,这个请求由于调用pcntl派生子进程执行任务,故这个ajax请求会长时间处于等待响应的状态,后面的请求是每隔400毫秒请求一次后台查找结果。如图一所示,第一个请求发送后,后面的请求一直处于阻塞状态,导致setInterval轮询的请求全部被hold住。当第一个请求任务全部执行完毕后,后面的请求基本在统一时刻去后台拉取结果,这个时候每个请求返回的结果是一摸一样的,也就是说轮询已经不存在实际意义。

在网上找了一些说法,肯定了jQuery是具有非常强大异步并发处理能力,同时也排除了浏览器导致阻塞的可能。从一些文章中找到一种说法是有可能session在使用session file的时候会lock住,导致多个请求会等待第一个请求结束使session file释放,并给出了使用session_write_close函数解决锁文件的问题。

PHP官方文档是有如下解释:

void session_write_close ( void )

End the current session and store session data.

Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.

在请求的队列逻辑前面加上session_write_close()函数,将session立即写入session file,释放文件,而不是php script执行完毕再写入file,再释放,这样可以避免file长时间锁住,而导致后面请求的逻辑不能读取session file。

改造后的效果非常明显,轮询结果恢复正常:

转自:http://leeon.me/a/persistent-link-poll-ajax-requests-with-php

Nginx中gzip_static模块的使用

在nginx中打开gzip压缩:

Nginx代码  收藏代码
  1. gzip  on;
  2. gzip_min_length  1024;
  3. gzip_buffers     4 8k;
  4. gzip_types       text/plain application/x-javascript text/css text/html application/xml;

一般情况,需要设置一下gzip_min_length的值,建议设置成大于1k的字节数,小于1k可能会越压越大。 即: gzip_min_length 1024
gzip_types:匹配MIME类型进行压缩,(无论是否指定)”text/html”类型总是会被压缩的。

另外nginx还提供了一个static_gzip模块,若要使用它需要在编译的时候把static_gzip模块编译进去:
./configure –with-http_gzip_static_module

此模块的作用就是在接到请求后,会到url相同的路径的文件系统去找扩展名为“.gz”的文件
比如:http://www.iteye.com/stylesheets/homepage.css
nginx就会先查找 stylesheets/homepage.css.gz 这个文件,如果存在直接把它发送出去,如果不存在,再将stylesheets/homepage.css文件进行gzip压缩,再发送出去,这样可以避免重复的压缩无谓的消耗资源,这个模块不受gzip_types限制,会对所有请求有效。所以建议不要在全局上使用,因为一般来说大部分都是动态请求,是不会有.gz这个文件的,建议只在局部我们确认有.gz的目录中使用。
Nginx不会自动的将压缩结果写入文件系统,这点不同于lighttpd,所以如果想使用static_gzip模块,需要自己写脚本生成.gz文件。
而对于Rails3项目来说就很方便了,只需要针对assets目录启用gzip_static模块即可:

Nginx代码  收藏代码
  1. location ~ ^/(assets)/  {
  2.   root /path/to/public;
  3.   gzip_static on; # to serve pre-gzipped version
  4.   expires max;
  5.   add_header Cache-Control public;
  6. }

前端性能优化

一、 前端性能黄金法则:
只有10%-20%的最终用户响应时间是花在了下载HTML源文件上。其他80%-90%是花在了下载页面中的所有组件上。 80%-90%用户的等待时间是来自于前端的页面加载
二、时间花在哪?
Blocked:包括所有预处理(查询本地Cache)时间和等待网络连接可用的时间
DNS Lookup:域名解析。查询过程:浏览器DNS缓存;操作系统DNS缓存;DNS服务器。
Connect:创建一个 TCP 连接到 web 服务器 (或代理) 所需的时间。如果正在使用安全的 HTTPS 连接这次包括 SSL 握手过程。
Send:HTTP 请求消息发送到服务器所需的时间,将取决于发送到服务器的数据量。
Wait:等待来自服务器的响应消息。此值包括由于采用网络延迟的延误和处理该请求的 web 服务器上所需的时间。
Receive:从服务器读取响应消息所需的时间。此值将取决于内容返回,网络带宽的大小和是否使用 HTTP 压缩了。
Cache Read:读取浏览器缓存中的内容或 304 响应所需的时间。
TTFB:(Time To First Byte)从初始的网络请求正在发起由浏览器从服务器接收的第一个字节的持续时间。它包括 TCP 连接时间、 将请求发送时间和获取响应消息的第一个字节的时间。
Network:所有的网络相关的 HTTP 请求的总持续时间。
三、优化方向
Blocked:增加expires头,配置Etag 参考:expires与etag控制页面缓存的优先级
DNS Lookup:减少DNS查询,2个域名要优于1个和4个域名(yahoo)参考: 网站加速最佳实践 –减少DNS查找
Connect:Connect:keep-alive ; CDN
Send:将图片,js,css独立服务器,避免每次请求中带Cookie;Cookie domain尽量使用子域名;尽量使用GET方式请求。
Wait:服务器缓存;生成静态页面;服务器负载均衡;重定向;SQL语句优化;SQL索引等服务器后端处理速度。
Receive:带宽;Gzip;Html/Js/Css压缩;Js混淆;Image Map;降低图片质量;精简HTMl等
如何减少Http请求次数:
合并js文件;合并css文件;css sprites;image地图;将图片编码成base64数据嵌入网页
如何减少阻塞次数、减少阻塞时间
将css放在顶部;将js放在底部;删除重复的脚本;延迟加载熏染页面不需要的脚本;按需异步下载脚本
四、相关工具——监控工具:
IE FireFox Chrome
IE Developer Tools Firebug Chrome Developer Tools
Httpwatch Speed Tracer
Fiddler – -
五、 相关工具——分析(提供优化)
YSlow;PageCheck性能检测工具;百度统计;page speed

nginx 配置应付高并发[转]

一、一般来说nginx 配置文件中对优化比较有作用的为以下几项:

1.  worker_processes 8;

nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计为8)。

2.  worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

为每个进程分配cpu,上例中将8 个进程分配到8 个cpu,当然可以写多个,或者将一
个进程分配到多个cpu。

3.  worker_rlimit_nofile 65535;

这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文
件数(ulimit -n)与nginx 进程数相除,但是nginx 分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。

现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。

这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。

查看linux系统文件描述符的方法:

[root@web001 ~]# sysctl -a | grep fs.file

fs.file-max = 789972

fs.file-nr = 510 0 789972

4.  use epoll;

使用epoll 的I/O 模型

(

补充说明:

与apache相类,nginx针对不同的操作系统,有不同的事件模型

A)标准事件模型
Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
B)高效事件模型
Kqueue:使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
Epoll: 使用于Linux内核2.6版本及以后的系统。

/dev/poll:使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。

Eventport:使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装安全补丁。

)

5.  worker_connections 65535;

每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。

6.  keepalive_timeout 60;

keepalive 超时时间。

7.  client_header_buffer_size 4k;

客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。

分页大小可以用命令getconf PAGESIZE 取得。

[root@web001 ~]# getconf PAGESIZE

4096

但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。

8.  open_file_cache max=65535 inactive=60s;

这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。

9.  open_file_cache_valid 80s;

这个是指多长时间检查一次缓存的有效信息。

10.  open_file_cache_min_uses 1;

open_file_cache 指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。

二、关于内核参数的优化:

net.ipv4.tcp_max_tw_buckets = 6000

timewait 的数量,默认是180000。

net.ipv4.ip_local_port_range = 1024 65000

允许系统打开的端口范围。

net.ipv4.tcp_tw_recycle = 1

启用timewait 快速回收。

net.ipv4.tcp_tw_reuse = 1

开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。

net.ipv4.tcp_syncookies = 1

开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。

net.core.somaxconn = 262144

web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。

net.core.netdev_max_backlog = 262144

每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

net.ipv4.tcp_max_orphans = 262144

系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。

net.ipv4.tcp_max_syn_backlog = 262144

记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。

net.ipv4.tcp_timestamps = 0

时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

net.ipv4.tcp_synack_retries = 1

为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。

net.ipv4.tcp_syn_retries = 1

在内核放弃建立连接之前发送SYN 包的数量。

net.ipv4.tcp_fin_timeout = 1

如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。

net.ipv4.tcp_keepalive_time = 30

当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。

三、下面贴一个完整的内核优化设置:

vi /etc/sysctl.conf  CentOS5.5中可以将所有内容清空直接替换为如下内容:

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000

使配置立即生效可使用如下命令:
/sbin/sysctl -p

四、下面是关于系统连接数的优化

linux 默认值 open files 和 max user processes 为 1024

#ulimit -n

1024

#ulimit –u

1024

问题描述: 说明 server 只允许同时打开 1024 个文件,处理 1024 个用户进程

使用ulimit -a 可以查看当前系统的所有限制值,使用ulimit -n 可以查看当前的最大打开文件数。

新装的linux 默认只有1024 ,当作负载较大的服务器时,很容易遇到error: too many open files 。因此,需要将其改大。

解决方法:

使用 ulimit –n 65535 可即时修改,但重启后就无效了。(注ulimit -SHn 65535 等效 ulimit -n 65535 ,-S 指soft ,-H 指hard)

有如下三种修改方式:

1. 在/etc/rc.local 中增加一行 ulimit -SHn 65535
2. 在/etc/profile 中增加一行 ulimit -SHn 65535
3. 在/etc/security/limits.conf 最后增加:

* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535

具体使用哪种,在 CentOS 中使用第1 种方式无效果,使用第3 种方式有效果,而在Debian 中使用第2 种有效果

# ulimit -n

65535

# ulimit -u

65535

备注:ulimit 命令本身就有分软硬设置,加-H 就是硬,加-S 就是软默认显示的是软限制

soft 限制指的是当前系统生效的设置值。 hard 限制值可以被普通用户降低。但是不能增加。 soft 限制不能设置的比 hard 限制更高。 只有 root 用户才能够增加 hard 限制值。

五、下面是一个简单的nginx 配置文件:

user www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000
01000000;
error_log /www/log/nginx_error.log crit;
pid /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 204800;
events
{
use epoll;
worker_connections 204800;
}
http
{
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
keys_zone=TEST:10m
inactive=5m;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 4k;
fastcgi_buffers 8 4k;
fastcgi_busy_buffers_size 8k;
fastcgi_temp_file_write_size 8k;
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
server
{
listen 8080;
server_name backup.aiju.com;
index index.php index.htm;
root /www/html/;
location /status
{
stub_status on;
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
}
log_format access ‘$remote_addr — $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” $http_x_forwarded_for’;
access_log /www/log/access.log access;
}
}

六、关于FastCGI 的几个指令:

fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10minactive=5m;

这个指令为FastCGI 缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。

fastcgi_connect_timeout 300;

指定连接到后端FastCGI 的超时时间。

fastcgi_send_timeout 300;

向FastCGI 传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI 传送请求的超时时间。

fastcgi_read_timeout 300;

接收FastCGI 应答的超时时间,这个值是指已经完成两次握手后接收FastCGI 应答的超时时间。

fastcgi_buffer_size 4k;

指定读取FastCGI 应答第一部分需要用多大的缓冲区,一般第一部分应答不会超过1k,由于页面大小为4k,所以这里设置为4k。

fastcgi_buffers 8 4k;

指定本地需要用多少和多大的缓冲区来缓冲FastCGI 的应答。

fastcgi_busy_buffers_size 8k;

这个指令我也不知道是做什么用,只知道默认值是fastcgi_buffers 的两倍。

fastcgi_temp_file_write_size 8k;

在写入fastcgi_temp_path 时将用多大的数据块,默认值是fastcgi_buffers 的两倍。

fastcgi_cache TEST

开启FastCGI 缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU 负载,并且防止502 错误。

fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;

为指定的应答代码指定缓存时间,如上例中将200,302 应答缓存一小时,301 应答缓存1 天,其他为1 分钟。

fastcgi_cache_min_uses 1;

缓存在fastcgi_cache_path 指令inactive 参数值时间内的最少使用次数,如上例,如果在5 分钟内某文件1 次也没有被使用,那么这个文件将被移除。

fastcgi_cache_use_stale error timeout invalid_header http_500;

不知道这个参数的作用,猜想应该是让nginx 知道哪些类型的缓存是没用的。以上为nginx 中FastCGI 相关参数,另外,FastCGI 自身也有一些配置需要进行优化,如果你使用php-fpm 来管理FastCGI,可以修改配置文件中的以下值:

<value name=”max_children”>60</value>

同时处理的并发请求数,即它将开启最多60 个子线程来处理并发连接。

<value name=”rlimit_files”>102400</value>

最多打开文件数。

<value name=”max_requests”>204800</value>

每个进程在重置之前能够执行的最多请求数。

转自:http://hi.baidu.com/seo_php_ajax/item/cbba43dff7ca5cee3cc2cb72

Tesseract 3 语言数据的训练方法[转]

需要用到的程序

(1) Tesseract 3.00
(2) Tesseract 3.00 Bugfix
(3) CowBoxer 1.01
(4) Universal Extractor 1.61 (非必需)

使用 Universal Extractor 将 Tesseract 的安装包解开,再用 Bugfix 里的 tesseract.exe 覆盖原来的主程序,Tesseract 就可用了。CowBoxer 是用于修改 box 文件的程序。

生成第一个 box 文件

演示中将 Tesseract 解压到了 E:\tesseract-ocr 目录。然后在该目录中建立了一个 build 目录用于存放原始数据和训练过程中生成的文件。原始图片数据一个有 3 个 (test.001.tif – test.003.tif):



首先生成第一个图片 test.001.tif 的 box 文件,这里使用官方的 eng 语言数据进行文字识别:

E:\tesseract-ocr\build>..\tesseract test.001.tif test.001 -l eng batch.nochop makebox
Tesseract Open Source OCR Engine with Leptonica
Number of found pages: 1.

执行完这个命令之后,build 目录下就生成了一个 test.001.box。使用 CowBoxer 打开这个 box 文件,CowBoxer 会自动找到同名的 tif 文件显示出来。

CowBoxer 的使用方法可以看 Help -> About 中的说明。修改完成之后 File -> Save box file 保存文件。

生成初始的 traineddata

接下来使用这一个 box 文件先生成一个 traineddata,在接下来生成其他图片的 box 文件时,使用这个 traineddata 有利于提高识别的正确率,减少修改次数。

..\tesseract test.001.tif test.001 nobatch box.train
..\training\unicharset_extractor test.001.box
..\training\mftraining -U unicharset -O test.unicharset test.001.tr
..\training\cntraining test.001.tr
rename normproto test.normproto
rename Microfeat test.Microfeat
rename inttemp test.inttemp
rename pffmtable test.pffmtable
..\training\combine_tessdata test.

在 build 目录下执行完这一系列命令之后,就生成了可用的 test.traineddata。

生成其余 box 文件

将上一步生成的 test.traineddata 移动到 tesseract-ocr\tessdata 目录中,接下来生成其他 box 文件时就可以通过 -l test 参数使用它了。

..\tesseract test.002.tif test.002 -l test batch.nochop makebox
..\tesseract test.003.tif test.003 -l test batch.nochop makebox

这里仅仅是使用 3 个原始文件作为例子。实际制作训练文件时,什么时候生成一个 traineddata 根据情况而定。中途生成 traineddata 的目的只是为了提高文字识别的准确率,使后面生成的 box 文件能少做修改。

生成最终的 traineddata

在所有的 box 都制作完成后,就可以生成最终的 traineddata 了。

..\tesseract test.001.tif test.001 nobatch box.train
..\tesseract test.002.tif test.002 nobatch box.train
..\tesseract test.003.tif test.003 nobatch box.train
..\training\unicharset_extractor test.001.box test.002.box test.003.box
..\training\mftraining -U unicharset -O test.unicharset test.001.tr test.002.tr test.003.tr
..\training\cntraining test.001.tr test.002.tr test.003.tr
rename normproto test.normproto
rename Microfeat test.Microfeat
rename inttemp test.inttemp
rename pffmtable test.pffmtable
..\training\combine_tessdata test.

在文件较多时可以用程序生成这种脚本执行。

转自:http://blog.wudilabs.org/entry/f25efc5f/

关于团队执行力的思考[转]

周一的执行力培训后个人有些思考,现与各位分享,欢迎拍砖,讨论
要有好的团队执行力最重要也是最基本的一个前提是态度。leader要有积极的态度想要去带好团队,员工要有积极的态度去把工作做好,积极的配合 leader及与其他同事的良好沟通与配合。若leader与组员都是一种消极的态度,得过且过,做一天和尚撞一天钟且还不能把钟撞好那执行力也无从说起 了。
兵熊熊一个,将熊熊一窝,首先如果做为leader没有一个好的积极的态度,那好比一组齿轮失去了一个核心齿轮,整个齿轮组系统无法运作或不能发挥最佳性 能的运作;而下边的成员其中一个没有好的工作态度也可能会导致整个齿轮系统运转不流畅。《亮剑》中曾提到,打了败仗不要紧,只要根基还在就能卷土重来,但 是首先要解决的士气问题!也就是每个战士的态度问题。
那怎么样算是好的工作态度呢?
热爱自己的工作,在工作中积极主动的去思考问题,发现问题,人人都是产品经理忘掉“设计就是这样的”,忘记“原型就是这样的”,忘记“这个实现起来太难 了”,忘记“这块不是我负责的,不关我事”……要有做出最好,最精的产品的霸气与自信,并且要以做出最好,最精产品为目标。
时刻保持一颗学习的心,也是好的工作态度不可或缺的一部分,只有不断地学习提升自升的实力,把自己所学与团队成员分享让团队成员整体实力得到提升,来增强 团队的核心竞争力,这样才能更好的提升团队的执行力。

一个团队应该有团队自身的团队文化,团队的一个理念以及信念。这个需要团队所有成员在合作与沟通中去发现。leader应该要善于发现每个成员的个性,特 长,量才而用,挖掘出各成员的潜在的实力。善于引导成员走上更好的发展方向,带领整个团队走向正确的更理想的一个发展方向。每个团队也应该要有自己的核心 竞争力。

什么是执行力,就是把目标变成结果的行动的能力。
经常会有人说起,比如学生,我在这次考试中已经很努力了,付出了很多可是为什么我没有考得好的结果呢?也有人会说起,这次工作中我已经尽力了,结果却远不 是自己所想要的……会有很多的人更加享受努力,奋斗的过程但是太多的情景或场合人们关注的只是结果,没有人关心你在此之前有多么的努力。所以我们在努力拼 搏享受过程的时候更多的应该考虑到结果,更多的应该为结果负责而不是只对程序,对形式,对苦劳负责。比如在培训过程中讲师所提到的挖井的漫画,图中主角很 努力的挖了一天,挖了五口井却没有一口井出水,他很辛苦,他很努力可是没有出水的结果,那么多数人给出的评论将是他今儿的活儿白干了,他没有尽力。还有从 另外一个角度来看那幅漫画是,工作需要一种韧性,需要一种持之以恒的态度,坚持才能走向胜利!
在工作中我们应该以结果做为导向,要知道我们做一件事情所要得到的结果是什么。这个问题会在我们项目开发中经常遇到,下面说下4R管理体系:
1,结果定义:不要给员工说”我以为“的机会。项目开发前期碰需求的时候开发人员,产品经理,测试在会议室整天整天的待着,既然花了那么些时间一定要把需 求吃透,这个模块的逻辑是怎么样的,要得到一个什么样的结果或者说是效果,有没有更深层的逻辑,有没有潜在的逻辑没有分析到,有没有产品经理没有考虑到或 者考虑得不正确的逻辑。做到每个与会人员对需求都吃透。并且不要只是产品经理在说,组长在记两个人讨论得热火嘲天到了开发期review代码时发现逻辑不 对,再讨论时得到的答案是“我以为如何如何……”,结果是已经开发完的模块重新再来,浪费时间,影响进度。与会的每个人都应该积极主动的讨论,思考,记录 (任务较多,难免会在开发一段时间后逻辑混淆……)

2,一对一责任:不给员工推卸责任的机会。每个小组每天早上都应该要有一个简短的站立会,对前一天的开发任务,代码,遇到问题一一陈述,而且也不能是各说 个的,leader应该发起提问,让每个组员都能精神集中起来,不仅关心自己所负责的部分还要关心其他同事所负责的部分,看看别人遇到了什么问题,如何解 决的对自己有没有帮助,自己会不会或者有没有碰到同样的问题,自己有没有更好的解决办法,有的话提出自己的想法……整个项目当前处在一个什么样的进度,是 提前了还是延迟了。然后各自说一下当天的工作计划。在组员自己给自己分配任务(主动接受)或者leader给组员分配任务(被动接受)都要明确到人,之后 发现哪块有问题能最快速的找到开发人或负责人来及时的处理解决问题,且开发人或负责人没有推卸责任的机会,当初就是分配给他的,没有其他人。

3,过程检查:Review代码,Review进度。对于项目来说,代码是相当重要的,好的代码很大程度上决定了项目的好坏,性能是不是达到预期效果(有 没有多余的请求,有没有过多的数据库连接),逻辑是否与讨论时一致……小组每周应该有一次代码的review,看看代码中的问题要做出及时的修正,并且要 在之后的开发过程中如何有效的避免这类问题,找出更好的解决方案。看看哪些代码,哪些解决方案是比较好的,有没有更好的写法,更好的解决方案在之后的开发 中可以借鉴及优化。除了代码的Review还要对整个项目的进度Review,现在整个项目进度是怎么样的一个进展情况,是否有延迟,若有应该想办法加快 进度。控制项目进度也是执行力中很重要的一部分能力,其他不说在deadline时没有按时交付团队执行力就已经大打折扣了。既然分解时已经承诺了期限就 应该全力以赴,说到做到。执行力的三大标准信守承诺排在第一位。

4,即时的激励:有奖有罚,对于表现好的公司或团队就应该有所鼓励,对于表现不好的也应该有所惩罚,奖罚分明。这样才能让表现好的继续保持,再接再励也能 让表现不好的以鞭策,否则表现优秀与表现不尽人意得到的结果是一样,谁心里都不会服气。导致的结果可能是之前表现优秀的也开始消极待工,甚至可能辞职走 人……

执行力的三大标准:
1,信守承诺:应承的事情就应该说到做到,不要找借口,也不要推卸责任,对自己的工作负责也是好的工作态度的一个重要组成部分。今日事今日毕,不要总觉得 deadline还未到还有时间,可以放到明天做。因为有些时候没办法预料到在之后的工作中会碰到哪些更棘手的问题,会要花费更多的时间去处理。
2,结果导向:对程序,对形式,对苦劳负责,更加要对自己工作的结果负责。工作中不但要明确自己要做什么而且更加要明确自己所做事情最后要得到一个什么样 的结果。比如我们在做KPI的时候会要求有一个可衡量的标准,不能只是说努力做好什么,尽全力做好什么,这种都是无法控制无法衡量的。应该是具体到做怎么 样的一件事,有什么样的结果来衡量。比如做一次XX技术的分享,有没有做分享这一看就知道…
3,永不言败:做为一个开发人员就应该有这样一种自信,我自己写出的东西就是最好的(当然虚心学习肯定是不能少的!),碰到问题应该及时寻求答案或与团队 成员沟通(既然是团队执行力,那么团队间的合作,沟通是非常重要的部分)而不要去想着遇到问题解决不了自己实力不行了如何如何,而是要想着“老子还不信邪 了,搞不定你?!”。

狼性团队:
李云龙说过,知道我最喜欢哪种动物吗?狼!狼这种畜生又凶又滑,尤其是群狼老虎见了都得怕三分!咱独立团的战士都是狼,一群嗷嗷叫的狼!
团队间默契的合作是一个优秀团队不可或缺的元素!然后把羊放到狼群中,假设狼暂时改吃素了,不吃羊了也愿意羊的加入但是这支“狼群”绝对没有纯粹的狼群战 斗力强。
转自:http://www.cnblogs.com/think_fish/archive/2012/06/14/2549941.html

Sqlserver快速删除特定分区数据的方法

在sqlserver中的partition並沒有可以直接使用truncate的動作
但有下面的方式是可以做到truncate的動作

使用$PARTITION找出要parttion no

DECLARE @PARTITION_DEL_NO NVARCHAR(4)
–找出parttion 2009/01/01這區塊的parttion no
SELECT @PARTITION_DEL_NO=$PARTITION.test_DT_FN(’2009/01/01′)
select @PARTITION_DEL_NO

–做parttion搬移動作
ALTER TABLE test SWITCH PARTITION ‘+@PARTITION_DEL_NO+’ TO dbo.Old_test
此段是將test的parttion 2區塊直接指定給Old_test的parttion
資料是瞬間過去因為他是指標指過去給Old_test所以根本就沒有做資料匯出匯入
這樣就等於做了truncate的動作一樣,資料到Old_test後在做truncate table Old_test這樣就ok了

要注意的事,Old_test的table欄位要跟test一模一樣這樣才能搬且在搬時Old_test不能有資料所以要先對Old_test做truncate再搬

大家可以參考一下

SQL Server 2005中的分区表(六)[转]

将已分区表转换成普通表
我的俄罗斯名叫作“不折腾不舒服斯基”,所以,不将分区表好好折腾一下,我就是不舒服。

在前面,我们介绍过怎么样直接创建一个分区表,也介绍过怎么将一个普通表转换成一个分区表。那么,这两种方式创建的表有什么区别呢?现在,我又最新地创建了两个表:

第一个表名为Sale,这个表使用的是《SQL Server 2005中的分区表(一):什么是分区表?为什么要用分区表?如何创建分区表?》中的方法创建的,在创建完之后,还为该表添加了一个主键。

第二个表名Sale1,这个表使用的是《SQL Server 2005中的分区表(三):将普通表转换成分区表 》中的方法创建的,也就是先创建了一个普通表,然后通过为普通表添加聚集索引的方式将普通表转换成已分区表的方式。

通过以上方法都可以得到一个已分区表,但是,这两个已分区表还是有点区别的,区别在哪里呢?我们分别查看一下这两个表的索引和主键吧,如下图所示。

从上图可以看出,直接创建的分区表Sale的索引里,只有一个名为PK_Sale的索引,这个索引是唯一的、非聚集的索引,也就是在创建PK_Sale主键时SQL Server自动创建的索引。而经普通表转换成分区表的Sale1的索引里,除了在创建主键时由SQL Server自动创建的名为PK_Sale1的唯一的、非聚集的索引之外,还存在一个名为CT_Sale1的聚集索引。

对于表Sale来说,可以通过修改分区函数的方式来将其转换成普通表,具体的修改方式请看《SQL Server 2005中的分区表(四):删除(合并)一个分区》,事实上,就是将分区函数中的所有分区分界都删除,那么,这个分区表中的所有数据就只能存在第一个分区表中了。在本例中,可以使用以下代码来修改分区函数。

[csharp]
ALTER PARTITION FUNCTION partfunSale()
MERGE RANGE (’20100101′)
ALTER PARTITION FUNCTION partfunSale()
MERGE RANGE (’20110101′)
ALTER PARTITION FUNCTION partfunSale()
MERGE RANGE (’20120101′)
ALTER PARTITION FUNCTION partfunSale()
MERGE RANGE (’20130101′)
[/csharp]

事实上,这么操作之后,表Sale还是一个分区表,如下图所示,只不过是只有一个分区的分区了,这和普遍表就没有什么区别了。

对于通过创建分区索引的方法将普通表转换成的分区表而言,除了上面的方法之外,还可以通过删除分区索引的办法来将分区表转换成普通表。但必须要经过以下两个步骤:

1、删除分区索引

2、在原来的索引字段上重建一个索引。

先说删除分区索引吧,这一步很简单,你可以直接在SQL Server Management Studio上将分区索引删除,也可以使用SQL语句删除,如本例中可以使用以下代码删除已经创建的分区索引。

[csharp]
drop index Sale1.CT_Sale1

[/csharp]

一开始,我还以为只要删除了分区索引,那么分区表就会自动转换成普通表了,可是在删除索引之后,查看一下该表的属性,结果还是已分区表,如下图所示。

不但如此,而且,还不能将原来的聚集的唯一索引(在本例中为主键的那个索引)改成聚集索引,如下图所示。

如果要彻底解决这个问题,还必须要在原来创建分区索引的字段上重新创建一下索引,只有重新创建过索引之后,SQL Server才能将已分区表转换成普通表。在本例中可以使用以下代码重新创建索引。

[csharp]
CREATE CLUSTERED INDEX CT_Sale1 ON Sale1([SaleTime])
ON [PRIMARY]
Go
[/csharp]

重建索引之后,分区表就变成了普通表,现在再查看一下Sale1表的属性,我们可以看到原来的分区表已经变成了普通表,如下图所示。

当然,以上两个步骤也可以合成一步完成,也就是在重建索引的同时,将原索引删除。如以下代码所示:

[csharp]
CREATE CLUSTERED INDEX CT_Sale1 ON Sale1([SaleTime])
WITH ( DROP_EXISTING = ON)
ON [PRIMARY]

[/csharp]

按理说,在SQL Server Management Studio中的操作和使用SQL语句的操作是一样的,可是我在SQL Server Management Studio中将聚集索引删除后再在该字段上重新创建一个同名的索引,并重新生成和组织该索引,可是分区表还是没有变成普通表,这就让我百思不得其解了。不过呢,只要能用SQL语句达到目的,那我们就用它吧。

SQL Server 2005中的分区表(五)[转]

添加一个分区
所谓天下大事,分久必合,合久必分,对于分区表而言也一样。前面我们介绍过如何删除(合并)分区表中的一个分区,下面我们介绍一下如何为分区表添加一个分区。

为分区表添加一个分区,这种情况是时常会 发生的。比如,最初在数据库设计时,只预计了存放3年的数据,可是到了第4天怎么办?这样的话,我们就可以为分区表添加一个分区,让它把新的数据放在新的分区里。再比如,最初设计时,一个分区用于存放一年的数据,结果在使用的时候才发现,一年的数据太多,想将一个分区中的数据分为两个分区来存放。

遇到这种情况,就必须要为分区表添加一个分区了。

当然,我们也可以使用修改分区函数的方式来添加一个分区,但是在修改分区函数时,我们必须要注意另一个问题——分区方案。为什么还要注意分区方案呢?我们回过头来看一下前面是怎么定义分区函数和分区方案的,如以下代码所示:

[csharp]
–添加分区函数
CREATE PARTITION FUNCTION partfunSale (datetime)
AS RANGE RIGHT FOR VALUES (’20100101′,’20110101′,’20120101′,’20130101′)
–添加分区方案
CREATE PARTITION SCHEME partschSale
AS PARTITION partfunSale
TO ( Sale2009, Sale2010, Sale2011, Sale2012, Sale2013)

[/csharp]
从以上代码中可以看出,分区函数定义了用于分区的数据边界,而分区函数指定了符合分区边界的数据存放在文件组。因此,分区方案中指定的文件组个数应该是比分区函数中指定的边界数大1的。如上例中,分区函数中指定的边界数为4,那么在分区方案中指定的文件组数就为5。

如果,我们将分区函数中的边界数增加一个,那么分区方案中的文件组数也就要相应地增加一个。因此,我们不能简简单单地通过修改分区函数的方式来为分区表添加一个分区。

那么,我们应该怎么做呢?是不是要先为分区方案添加一个文件组?

这种想法是没有错的,想要为分区表添加一个分区,可以通过以下两个步骤来实现:

1、为分区方案指定一个可以使用的文件组。

2、修改分区函数。

在为分区方案指定一个可用的文件组时,该分区方案并没有立刻使用这个文件组,只是将文件组先备用着,等修改了分区函数之后分区方案才会使用这个文件组(不要忘记了,如果分区函数没有变,分区方案中的文件组个数就不能变)。

为分区方案指定一个可用的文件组的代码如下所示:

[csharp]
ALTER PARTITION SCHEME partschSale
NEXT USED [Sale2010]
[/csharp]

其中:

1、ALTER PARTITION SCHEME意思是修改分区方案

2、partschSale是分区方案名

3、NEXT USED意思是下一个可使用的文件组

4、[Sale2010]是文件组名

为分区方案添加了下一个可使用的文件组之后,分区方案并没有立刻使用这个文件组,此时我们可以通过查看分区方案的源代码来证实。查看方法是:在SQL Server Management Studio中,选择数据库–>存储–>分区方案,右击分区方案名,在弹出的菜单中选择“编写分区方案脚本为”–>CREATE到–>新查询编辑器窗口,如下图所示:

为分区方案添加了下一个可使用的文件组之后,我们就可以动手修改分区函数了,使用代码如下所示:

[csharp]
ALTER PARTITION FUNCTION partfunSale()
SPLIT RANGE (’20100101′)
[/csharp]
其中:

1、ALTER PARTITION FUNCTION意思是修改分区函数

2、partfunSale()为分区函数名

3、SPLIT RANGE 意思是分割界限

4、’20100101′ 是用于分割的界限值

当然,我们在修改分区函数前后都可以统计一下各物理分区的数据记录情况,如以下代码所示:

[csharp]
–统计所有分区表中的记录总数
select $PARTITION.partfunSale(SaleTime) as 分区编号,count(id) as 记录数 from Sale group by $PARTITION.partfunSale(SaleTime)
–原来的分区函数是将2010-1-1之前的数据放在第1个分区表中,将2010-1-1至2011-1-1之间的数据放在第2个分区表中
–现在需要将2011-1-1之前的数据都放在第1个分区表中,也就是将第1个分区表和第2个分区表中的数据合并
–修改分区函数
ALTER PARTITION FUNCTION partfunSale()
SPLIT RANGE (’20100101′)
–统计所有分区表中的记录总数
select $PARTITION.partfunSale(SaleTime) as 分区编号,count(id) as 记录数 from Sale group by $PARTITION.partfunSale(SaleTime)
[/csharp]

以上代码的运行结果如下图所示:

从上图中可以看出,分区表中已经添加了一个分区,我们也可以再一次查看分区方案的源代码,如下图所示,这个时候分区方案也自动添加了一个文件组。