月度归档:2012 年八月

C# HTTPWEBREQUEST可断点上传,下载文件;SOCKET多线程多管道可断点传送大文件[转]

HttpWebRequest
[csharp]
using System;
using System.Net;
using System.Web;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;

namespace Rocky.Net
{
public class HttpWalker
{
#region StaticMembers
public static void DownloadFile(HttpContext context, string filePath)
{
AppRuntime.Guard<ArgumentNullException>(context == null);
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
Response.Clear();
Response.Buffer = false;
Response.AddHeader("Accept-Ranges", "bytes");
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] buffer = BufferUtility.GetBuffer((int)stream.Length);
long p = 0L, l = stream.Length;
#region Resolve Range
string range = Request.Headers["Range"];
if (range != null)
{
//Range:bytes=1024-
//Range:bytes=1024-2048
//Range:bytes=-1024
//Range:bytes=0-512,1024-2048
int index = range.IndexOf("=");
if (index != -1)
{
string[] ranges = range.Substring(index + 1).Split(‘,’);
if (ranges.Length > 1)
{
//not supported multipart/byterange
}
else
{
bool flag = false;
if (ranges[0].StartsWith("-"))
{
long _p, _absp;
if (long.TryParse(ranges[0], out _p) && (_absp = Math.Abs(_p)) <= l)
{
if (_p < 0)
{
p = l – _absp;
l = _absp;
flag = true;
}
}
}
else
{
ranges = ranges[0].Split(‘-’);
if (ranges.Length == 2)
{
long _p, _l;
if (ranges[1] == string.Empty)
{
if (long.TryParse(ranges[0], out _p) && _p <= l)
{
p = _p;
flag = true;
}
}
else if (long.TryParse(ranges[0], out _p) && long.TryParse(ranges[1], out _l) && _p > 0 && _l > 0 && _p < _l && _l < l)
{
p = _p;
l = _l + 1;
flag = true;
}
}
}
if (flag)
{
Response.StatusCode = 206;
Response.AddHeader("Content-Range", "bytes " + p.ToString() + "-" + l.ToString() + "/" + stream.Length.ToString());
}
else
{
Response.StatusCode = 416; //Requested range not satisfiable
}
}
}
}
#endregion
Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filePath), Encoding.UTF8));
Response.AddHeader("Content-Length", l.ToString());
Response.ContentType = "application/octet-stream";
stream.Position = p;
int read;
while (Response.IsClientConnected && p < l)
{
Response.OutputStream.Write(buffer, 0, read = stream.Read(buffer, 0, buffer.Length));
Response.Flush();
p += read;
}
}
Response.End();
}

public static void UploadFile(HttpContext context, string savePath)
{
AppRuntime.Guard<ArgumentNullException>(context == null);
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
string msg = "0", fileName = Request.Headers["filename"];
if (fileName != null)
{
FileInfo file = new FileInfo(Path.Combine(Path.GetDirectoryName(savePath), fileName));
if (Request.Headers["breakpoint"] == bool.TrueString)
{
Response.AddHeader("Content-Length", (file.Exists ? file.Length : 0L).ToString());
}
else
{
long l;
if (Request.Files.Count > 0 && long.TryParse(Request.Headers["breakpoint"], out l))
{
HttpPostedFile postedFile = Request.Files[0];
using (FileStream stream = file.Open(file.Exists ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.None))
{
byte[] buffer = BufferUtility.GetBuffer((int)stream.Length);
Stream postedStream = postedFile.InputStream;
long p = stream.Position;
int read;
while (Response.IsClientConnected && p < l)
{
stream.Write(buffer, 0, read = postedStream.Read(buffer, 0, buffer.Length));
stream.Flush();
p += read;
}
}
file.MoveTo(savePath);
msg = "1";
}
}
}
Response.Write(msg);
Response.End();
}
#endregion

#region Fields
private HttpWebRequest httpRequest;
private CookieContainer cookieContainer;
private string referer;
private NameValueCollection form;
private List<HttpFile> files;
#endregion

#region Properties
public Uri RequestUri
{
set { httpRequest = (HttpWebRequest)WebRequest.Create(value); }
get { return httpRequest.RequestUri; }
}
public HttpWebRequest Request
{
get { return httpRequest; }
}
public CookieCollection Cookies
{
get { return cookieContainer.GetCookies(httpRequest.RequestUri); }
}
public NameValueCollection Form
{
get
{
if (form == null)
{
form = new NameValueCollection();
}
return form;
}
}
public List<HttpFile> Files
{
get
{
if (files == null)
{
files = new List<HttpFile>();
}
return files;
}
}
#endregion

#region Constructor
public HttpWalker(Uri uri)
{
this.RequestUri = uri;
cookieContainer = new CookieContainer();
referer = "http://www.google.com";
}
#endregion

#region Methods
public long GetContentLengthByHead()
{
return GetContentLengthByHead(true);
}
public long GetContentLengthByHead(bool reset)
{
using (HttpWebResponse httpResponse = GetResponse(WebRequestMethods.Http.Head))
{
if (reset)
{
httpRequest = (HttpWebRequest)WebRequest.Create(httpRequest.RequestUri);
}
return httpResponse.ContentLength;
}
}

public HttpWebResponse GetResponse()
{
if ((form != null && form.Count > 0) || (files != null && files.Count > 0))
{
return GetResponse(WebRequestMethods.Http.Post);
}
else
{
return GetResponse(WebRequestMethods.Http.Get);
}
}
public HttpWebResponse GetResponse(string method)
{
if (httpRequest.RequestUri.Scheme == "https")
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
}
httpRequest.CookieContainer = cookieContainer;
httpRequest.Referer = referer;
httpRequest.Accept = "*/*";
httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
if ((httpRequest.Method = method) == WebRequestMethods.Http.Post)
{
StringBuilder sb = new StringBuilder();
if (files.Count > 0)
{
Queue methodQueue = new Queue();
string boundary = Guid.NewGuid().ToString().Replace("-", string.Empty), line = "\r\n";
byte[] beginBoundary = Encoding.ASCII.GetBytes("–" + boundary + line);
//byte[] endBoundary = Encoding.ASCII.GetBytes("–" + boundary + "–" + newLine);
httpRequest.ContentType = "multipart/form-data; boundary=" + boundary;
long contentLength = 0L;
if (form != null && form.Count > 0)
{
for (int i = 0; i < form.Count; i++)
{
sb.Length = 0;
sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n", form.GetKey(i));
sb.AppendFormat("{0}\r\n", form.Get(i));
byte[] header = Encoding.UTF8.GetBytes(sb.ToString());
contentLength += beginBoundary.LongLength + header.LongLength;
methodQueue.Enqueue(new Action<Stream>(stream =>
{
stream.Write(beginBoundary, 0, beginBoundary.Length);
stream.Write(header, 0, header.Length);
}));
}
}
if (files != null)
{
sb.Length = 0;
sb.Append(line);
sb.Append("–" + boundary + line);
byte[] endOfFile = Encoding.ASCII.GetBytes(sb.ToString());
files.ForEach(file =>
{
sb.Length = 0;
sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", file.FieldName, Path.GetFileName(file.FileName));
sb.Append("Content-Type: application/octet-stream\r\n\r\n");
byte[] header = Encoding.UTF8.GetBytes(sb.ToString());
contentLength += beginBoundary.LongLength + header.LongLength + file.ContentLength + endOfFile.LongLength;
methodQueue.Enqueue(new Action<Stream>(stream =>
{
stream.Write(beginBoundary, 0, beginBoundary.Length);
stream.Write(header, 0, header.Length);
file.WriteTo(stream);
stream.Write(endOfFile, 0, endOfFile.Length);
}));
});
}
httpRequest.ContentLength = contentLength;
Stream requestStream = httpRequest.GetRequestStream();
while (methodQueue.Count > 0)
{
((Action<Stream>)methodQueue.Dequeue())(requestStream);
}
requestStream.Close();
}
else
{
if (form != null && form.Count > 0)
{
httpRequest.ContentType = "application/x-www-form-urlencoded";
sb.Append(form.GetKey(0)).Append("=").Append(form.Get(0));
for (int i = 1; i < form.Count; i++)
{
sb.Append("&").Append(form.GetKey(i)).Append("=").Append(form.Get(i));
}
byte[] data = Encoding.UTF8.GetBytes(sb.ToString());
httpRequest.ContentLength = data.LongLength;
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
}
}
}
HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
referer = httpResponse.ResponseUri.AbsoluteUri;
return httpResponse;
}
//https
private bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors)
{
// Always accept
return true;
}

public void Reset(Uri uri)
{
this.RequestUri = uri;
cookieContainer = new CookieContainer();
referer = "http://www.google.com";
if (form != null)
{
form.Clear();
}
if (files != null)
{
files.Clear();
}
}
public void RefreshCookies()
{
cookieContainer = new CookieContainer();
}

public override string ToString()
{
HttpWebResponse httpResponse = GetResponse();
using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream(), Encoding.GetEncoding(httpResponse.CharacterSet ?? "gb2312")))
{
return reader.ReadToEnd();
}
}
#endregion

#region File
public void DownloadFile(string savePath)
{
using (FileStream stream = new FileStream(savePath, File.Exists(savePath) ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
httpRequest.AddRange((int)stream.Length);
HttpWebResponse response = GetResponse();
byte[] buffer = new byte[BufferUtility.FileBufferSize];
Stream responseStream = response.GetResponseStream();
long p = stream.Length, l = response.ContentLength;
int read;
while (p < l && (read = responseStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, read);
stream.Flush();
p += read;
}
responseStream.Close();
}
}

public string UploadFile(string filePath)
{
string fileName = Path.GetFileName(filePath);
string base64FileName = Convert.ToBase64String(Encoding.ASCII.GetBytes(fileName));
httpRequest.Headers["filename"] = base64FileName;
httpRequest.Headers["breakpoint"] = bool.TrueString;
long p = GetContentLengthByHead(), l;
string boundary = DateTime.Now.Ticks.ToString("x"), line = "\r\n";
StringBuilder sb = new StringBuilder();
sb.Append("–").Append(boundary).Append(line);
sb.Append("Content-Disposition: form-data; name=\"file\"; ").Append("filename=\"").Append(fileName).Append("\"").Append(line);
sb.Append("Content-Type: application/octet-stream").Append(line);
sb.Append(line);
byte[] headerBytes = Encoding.UTF8.GetBytes(sb.ToString());
sb.Length = 0;
sb.Append(line);
sb.Append("–").Append(boundary).Append(line);
byte[] endOfFile = Encoding.ASCII.GetBytes(sb.ToString());
httpRequest.Method = WebRequestMethods.Http.Post;
httpRequest.AllowWriteStreamBuffering = false;
httpRequest.Timeout = 300000;
httpRequest.ContentType = "multipart/form-data; boundary=" + boundary;
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
httpRequest.Headers["filename"] = base64FileName;
httpRequest.Headers["breakpoint"] = stream.Length.ToString();
stream.Position = p;
l = stream.Length;
httpRequest.ContentLength = headerBytes.Length + (l – p) + endOfFile.Length;
byte[] buffer = BufferUtility.GetBuffer((int)stream.Length);
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(headerBytes, 0, headerBytes.Length);
int read;
while (p < l)
{
requestStream.Write(buffer, 0, read = stream.Read(buffer, 0, buffer.Length));
requestStream.Flush();
p += read;
}
requestStream.Write(endOfFile, 0, endOfFile.Length);
requestStream.Close();
}
return ToString();
}
#endregion
}

#region HttpFile
public sealed class HttpFile
{
private long offset, length;
private byte[] binaryData;

public string FieldName { set; get; }
public string FileName { private set; get; }
public long ContentLength
{
get { return binaryData == null ? length : binaryData.LongLength; }
}

public HttpFile(string fieldName, string fileName)
{
this.FieldName = fieldName;
this.FileName = fileName;
FileInfo info = new FileInfo(fileName);
this.offset = 0L;
this.length = info.Length;
}
public HttpFile(string fieldName, string fileName, long offset, long length)
{
this.FieldName = fieldName;
this.FileName = fileName;
this.offset = offset;
this.length = length;
}

public HttpFile(string fieldName, string fileName, byte[] binaryData)
{
this.FieldName = fieldName;
this.FileName = fileName;
this.binaryData = binaryData;
}

public void WriteTo(Stream stream)
{
if (binaryData == null)
{
using (FileStream fileStream = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
byte[] buffer = BufferUtility.GetBuffer((int)fileStream.Length);
fileStream.Position = offset;
long done = 0L;
int read;
while (done < length)
{
stream.Write(buffer, 0, read = fileStream.Read(buffer, 0, buffer.Length));
stream.Flush();
done += read;
}
}
}
else
{
stream.Write(binaryData, 0, binaryData.Length);
stream.Flush();
}
}
}
#endregion
}
[/csharp]
上传Demo
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Rocky.Net;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//FileStream stream1 = new FileStream(@"F:\ToolsDev\fireworks8.zip", FileMode.Open);
//FileStream stream2 = new FileStream(@"d:\IE8.zip", FileMode.Create);
//long length = 1024L * 1024L * 8L;
//byte[] buffer = new byte[1024 * 4];
//int read;
//while (length > 0 && (read = stream1.Read(buffer, 0, buffer.Length)) != 0)
//{
// stream2.Write(buffer, 0, read);
// stream2.Flush();
// length -= read;
//}
//stream1.Close();
//stream2.Close();
//Response.End();
if (Request.QueryString["action"] == "server")
{
HttpWalker.UploadFile(this.Context, Server.MapPath("~/IE8.zip"));
}
else
{
try
{
HttpWalker w = new HttpWalker(new Uri("http://rocky.net?action=server"));
Response.Write(w.UploadFile(@"D:\fireworks8.zip"));
}
catch (Exception ex)
{
Response.Write(ex);
}
}
Response.End();
}

protected void Button1_Click(object sender, EventArgs e)
{

}
}
[/csharp]

PHP用CURL伪造IP和来源[转]

文件1.php 请求 文件2.php

1.php代码:
[php]
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘X-FORWARDED-FOR:8.8.8.8′, ‘CLIENT-IP:8.8.8.8′));//IP
curl_setopt($ch, CURLOPT_REFERER, "http://www.yzswyl.cn/ "); //来路
curl_setopt($ch, CURLOPT_HEADER, 1);
$out = curl_exec($ch);
curl_close($ch);
[/php]

2.php代码:
[php]
function getClientIp() {
if (!empty($_SERVER["HTTP_CLIENT_IP"]))
$ip = $_SERVER["HTTP_CLIENT_IP"];
else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if (!empty($_SERVER["REMOTE_ADDR"]))
$ip = $_SERVER["REMOTE_ADDR"];
else
$ip = "err";
return $ip;
}
echo "IP: " . getClientIp() . "";
echo "referer: " . $_SERVER["HTTP_REFERER"];
[/php]
伪造成功,这是不是给“刷票”的朋友提供了很好的换IP的方案!!

摘自:http://yzswyl.cn/blread-1540.html

Linux查看当前目录下文件的个数[转]

查看当前目录下文件的个数
ls -l | grep “^-” | wc -l
查看当前目录下文件的个数,包括子目录里的。
ls -lR| grep “^-” | wc -l
查看某目录下文件夹(目录)的个数,包括子目录里的。
ls -lR| grep “^d” | wc -l
简要说明:
ls -l
长列表输出该目录下文件信息(注意这里的文件,不同于一般的文件,可能是目录、链接、设备文件等)
grep “^-”
这里将长列表输出信息过滤一部分,只保留一般文件,如果只保留目录就是 ^d
wc -l
统计输出信息的行数,因为已经过滤得只剩一般文件了,所以统计结果就是一般文件信息的行数,又由于一行信息对应一个文件,所以也就是文件的个数

转自:http://yzswyl.cn/blread-1547.html

nginx压力测试[转]

  在运维工作中,压力测试是一项非常重要的工作。比如在一个网站上线之前,能承受多大访问量、在大访问量情况下性能怎样,这些数据指标好坏将会直接影响用户体验。

  但是,在压力测试中存在一个共性,那就是压力测试的结果与实际负载结果不会完全相同,就算压力测试工作做的再好,也不能保证100%和线上性能指标相同。面对这些问题,我们只能尽量去想方设法去模拟。所以,压力测试非常有必要,有了这些数据,我们就能对自己做维护的平台做到心中有数。

  目前较为常见的网站压力测试工具有webbench、ab(apache bench)、tcpcopy、loadrunner

  软件名称简介优缺点

  webbench由Lionbridge公司开发,主要测试每秒钟请求数和每秒钟数据传输量,同时支持静态、动态、SSL

  部署简单,静动态均可测试。适用于小型网站压力测试(单例最多可模拟3万并发)

  ab(apache bench)Apache自带的压力测试工具,主要功能用于测试网站每秒钟处理请求个数

  多见用于静态压力测试,功能较弱,非专业压力测试工具

  tcpcopy基于底层应用请求复制,可转发各种在线请求到测试服务器,具有分布式压力测试功能,所测试数据与实际生产数据较为接近后起之秀,主要用于中大型压力测试,所有基于 tcp的packets均可测试

  loadrunner压力测试界的泰斗,可以创建虚拟用户,可以模拟用户真实访问流程从而录制成脚本,其测试结果也最为逼真模拟最为逼真,并可进行独立的单元测试,但是部署配置较为复杂,需要专业人员才可以。

  下面,笔者就以webbench为例,来讲解一下网站在上线之前压力测试是如何做的。

  安装webbench

  #wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz

  #tar zxvf webbench-1.5.tar.gz

  #cd webbench-1.5

  #make && make install

  进行压力测试

  并发200时

  # webbench -c 200 -t 60 http://blog.luwenju.com/index.php

  参数解释:-c为并发数,-t为时间(秒)

  Webbench – Simple Web Benchmark 1.5

  Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

  Benchmarking: GET http://blog.luwenju.com/index.php

  200 clients, running 60 sec.

  Speed=1454 pages/min, 2153340 bytes/sec.

  Requests: 1454 susceed, 0 failed.

  当并发200时,网站访问速度正常

  并发800时

  #webbench -c 800 -t 60 http://blog.luwenju.com/index.php

  Webbench – Simple Web Benchmark 1.5

  Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

  Benchmarking: GET http://blog.luwenju.com/index.php

  800 clients, running 60 sec.

  Speed=1194 pages/min, 2057881 bytes/sec.

  Requests: 1185 susceed, 9 failed.

  当并发连接为800时,网站访问速度稍慢

  并发1600时

  #webbench -c 1600 -t 60 http://blog.luwenju.com/index.php

  Webbench – Simple Web Benchmark 1.5

  Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

  Benchmarking: GET http://blog.luwenju.com/index.php

  1600 clients, running 60 sec.

  Speed=1256 pages/min, 1983506 bytes/sec.

  Requests: 1183 susceed, 73 failed.

  当并发连接为1600时,网站访问速度便非常慢了

  并发2000时

  #webbench -c 2000 -t 60 http://blog.luwenju.com/index.php

  Webbench – Simple Web Benchmark 1.5

  Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

  Benchmarking: GET http://blog.luwenju.com/index.php

  2000 clients, running 60 sec.

  Speed=2154 pages/min, 1968292 bytes/sec.

  Requests: 2076 susceed, 78 failed.

  当并发2000时,网站便出现“502 Bad Gateway”,由此可见web服务器已无法再处理用户访问请求

  总结:

  1、压力测试工作应该放到产品上线之前,而不是上线以后

  2、测试时尽量跨公网进行,而不是内网

  3、测试时并发应当由小逐渐加大,比如并发100时观察一下网站负载是多少、打开是否流程,并发200时又是多少、网站打开缓慢时并发是多少、网站打不开时并发又是多少

  4、 应尽量进行单元测试,如B2C网站可以着重测试购物车、推广页面等,因为这些页面占整个网站访问量比重较大

lvs+keepalived生产环境中使用[转]

这是生产环境中一个项目,该公司的网站经常受到同行的ddos攻击,故需要搭建一个环境让攻击者攻击时候转到公司的假网站上。我的任务就是搭建抗攻击的假网站。
我的设计这样的lvs(+keepalived组成高可用)+LNMP+组成公司的假网站。总过8台机器6台web服务器2台lvs
为了保密,ip和真正地web都不。。。web只用两台代替。
1,配置准备
centos下的yum环境,keepalived-1.1.17.tar.gz,ipvsadm-1.24.tar.gz(这两个包可用在网上下载,也可以在下面的链接上下http://www.kuaipan.cn/file/id_4516853896446486.html
2,安装配置
配置时候要确保下面的连接正常ln -sv /usr/src/kernels/2.6.32-220.el6.i686/ linux,因为keepalived-1.1.17.tar.gz,ipvsadm-1.24.tar.gz这两个包的编译都依赖开发的内核。如果出现以下情况:

[root@localhost src]# ll
total 8
drwxr-xr-x 7 root root 4096 Mar 1 03:01 redhat
[root@localhost src]#
因为在装系统的时候没有装kernels的开发包这时候需要自己装
yum install kernel*
安装ipvsadm-1.24.tar.gz
tar xf ipvsadm-1.24.tar.gz
cd ipvsadm-1.24
make && make install
安装keepalived-1.1.17.tar.gz
tar xf keepalived-1.1.17.tar.gz
cd keepalived-1.1.17
./configure
确保./configure的结果是下面样子
Keepalived configuration
————————
Keepalived version : 1.1.17
Compiler : gcc
Compiler flags : -g -O2
Extra Lib : -lpopt -lssl -lcrypto
Use IPVS Framework : Yes
IPVS sync daemon support : Yes
Use VRRP Framework : Yes
Use LinkWatch : No
Use Debug flags : No
make && make install
cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/sbin/keepalived /usr/sbin/
3,配置keepalived的主备配置文件
vim /etc/keepalived/keepalived.conf
#######MASTER#####################
! Configuration File for keepalived
global_defs {
notification_email {
470499989@qq.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200
}
}
virtual_server 192.168.1.200 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP

real_server 192.168.1.117 80 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.1.118 80 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
#################BACKUP#########################
! Configuration File for keepalived
global_defs {
notification_email {
470499989@qq.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200
}
}
virtual_server 192.168.1.200 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP

real_server 192.168.1.117 80 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.1.118 80 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
如果在执行service keepalived start,启动不起来需要看日志
# tail /var/log/messages
Mar 30 12:05:15 localhost Keepalived_vrrp: bogus VRRP packet received on eth0 !!!
Mar 30 12:05:15 localhost Keepalived_vrrp: VRRP_Instance(VI_1) Dropping received VRRP packet…
Mar 30 12:05:16 localhost Keepalived_vrrp: ip address associated with VRID not present in received packet : -939415360
Mar 30 12:05:16 localhost Keepalived_vrrp: one or more VIP associated with VRID mismatch actual MASTER advert
#######如果是以上日志就是因为你所在的环境还有其他人在做keepalived,需要修改虚拟路由标识,因为默认是51.
#######如果还启动不了,那么你要是用的虚拟机做的实验的话,看看你虚拟机的时间date,这一点对虚拟机很重要的哟。
附加keepalived配置文件的解读
#####配置文件解读#####
! Configuration File for keepalived
global_defs {
notification_email { ###定义接收信息的邮件地址
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1 ####定义用于监控的smtp地址
smtp_connect_timeout 30
router_id LVS_DEVEL ###定义lvs负载均衡标示
}
vrrp_instance VI_1 { ###定义一个vrrp组
state MASTER ###本机在该组中的所属的角色,只有MASTER和BACKUP两种状态,并且需要大写这些单词。
interface eth0 ###对外提供服务的网络接口
virtual_router_id 51 ###虚拟路由标识
priority 100 ###本机的在vrrp组的优先级
advert_int 1 ###主备同步检查时间间隔
authentication { ###主备之间通信验证设置
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { ###虚拟ip地址,也就是vip地址。
192.168.200.16
}
}
virtual_server 192.168.200.100 443 { ###虚拟服务器定义,注意是ip+端口号
delay_loop 6 ###健康检查时间间隔,单位是秒。
lb_algo rr ###负载均衡调度算法,互联网应用常使用wlc。
lb_kind NAT ###负载均衡转发规则,一般包括DR、NAT、TUN3种。常用DR模型。
nat_mask 255.255.255.0 ###DR模式这项没有
persistence_timeout 50 ###会话保持时间,单位是秒。
protocol TCP ###转发协议
real_server 192.168.201.100 443 { ###定义realserver,real_server的值包括ip地址和端口号
weight 1 ###该realserver的权重
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}

本文出自 “gabylinux” 博客,请务必保留此出处http://gabylinux.blog.51cto.com/1593644/822168

c#判断网络连接是否正常的方法

今天给消息提示工具加入网络连接判断功能,当网络断开的时候,部分功能不能使用。

[csharp]
public class NetworkUtil
{
[DllImport("wininet.dll", EntryPoint = "InternetGetConnectedState")]
public extern static bool InternetGetConnectedState(out int conState, int reder);
[DllImport("sensapi.dll")]
private extern static bool IsNetworkAlive(out int connectionDescription);

static System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
static System.Net.NetworkInformation.PingReply res;

/// <summary>
/// 检查网络是否连接?
/// </summary>
/// <returns></returns>
public static bool IsConnectedToInternet()
{
//方法一,winapi,外网没用,可以用来检测内网是否连通,但有时不及时
//return CheckInternetGetConnectedState();

//方法二,winapi,外网没用,可以用来检测内网是否连通,可以及时反应网络连通情况,但是需要服务System Event Notification支持(系统默认自动启动该服务)。使用该函数,需要安装最新的SDK(如.net的)
//return CheckIsNetworkAlive();

//方法三,ping方式,找一个可以ping得通的网址来判断,感觉有点傻,如果此网站出现问题,此判断也会出错
return CheckPing("www.baidu.com");

//方法四,连接一个外网的ip和端口,不太稳定,有时会误报
//return CheckIP("61.158.133.74", 80);
}

private static bool CheckInternetGetConnectedState()
{
int Desc = 0;
return InternetGetConnectedState(out Desc, 0);
}

private static bool CheckIsNetworkAlive()
{
int flags;
return IsNetworkAlive(out flags);
}

private static bool CheckPing(string url)
{
try
{
res = ping.Send(url);
if (res.Status == System.Net.NetworkInformation.IPStatus.Success)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}

private static bool CheckIP(string ip, int port)
{
try
{
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient(ip, port);
if (client.Connected)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
[/csharp]
总结:如果只是判断内网是否通畅,建议使用上面两个,如果是判断外网,必须用下面两种,个人感觉用ping的方式可能更快更准确一点。

php5.3.5 编译bin下没有php-cgi[转]

转自:http://hi.baidu.com/hackers365/blog/item/7b3ff37eba99b32c0cd7da3f.html

今天编译了一个最新的php5.3.5,编译参数如下:

./configure –prefix=/usr/local/php5.3.25 –enable-fpm –with-openssl –with-pcre-regex –with-zlib –with-bz2 –with-curl –with-gd –with-gettext –enable-mbstring –with-mcrypt –with-mysql –with-pdo-mysql –enable-zip –with-pear

make

make install

开了php-fpm,运行php-fpm也正常。。nginx在前端访问phpinfo也可以。。但是ps aux|grep php-cgi的时候没有发现php-cgi进程。只有php-fpm进程,纳闷了。。。google后得到结论

以前的版本中需要–enable-fastcgi来开启fastcgi支持,会生成php-cgi文件,而到5.3以后则在内核中支持fastcgi。

nginx 502 解决方法参考

经常碰到Nginx 502 Bad Gateway 这个问题,提示

Jan 11 08:54:01.164292 [NOTICE] fpm_children_make(), line 352: child 10088 (pool default) started
Jan 11 08:54:01.164325 [WARNING] fpm_children_bury(), line 215: child 7985 (pool default) exited on signal 15 SIGTERM after 63.778601 seconds from start
查过网上的资源,基本都是认为是php线程打开文件句柄受限导致的错误。具体的解决的办法如下:
1、提升服务器的文件句柄打开打开
/etc/security/limits.conf : (增加)
*    soft    nofile    51200
*    hard    nofile    51200
# vi /etc/security/limits.conf 加上
* soft nofile 51200
* hard nofile 51200
2、提升nginx的进程文件打开数
nginx.conf : worker_rlimit_nofile 51200;
3、修改php-fpm.conf文件,主要需要修改2处
命令 ulimit -n 查看限制的打开文件数,php-fpm.conf 中的选项rlimit_files 确保和此数值一致。
 <value name=”max_requests”>10240</value>
<value name=”rlimit_files”>51200</value>
4、
# vi /etc/sysctl.conf
底部添加
fs.file-max=51200

完成以上修改,重启PHP,警告信息再也没了。
世界从此安宁,502 Bad Gateway 没有了。

麻雀虽小,五脏俱全:JSR311让Restful WebService变简单[转]

需求
公司有一个产品,包括前台WEB界面和多个后台服务,各个服务都需要在前面界面中进行配置和控制,以调整服务的行为。以前,配置文件都存放在数据库中,界面上修改配置后入库,并发送消息(Socket)通知特定的服务重新加载配置。这样有些问题,一方面自己维护Socket带来很多麻烦,二来数据库重建的时候,需要备份/恢复这些配置数据。

所以,我们想把配置文件局部化到各个服务(比如用本地文件存储),然后在界面上修改的时候,实时向服务请求当前配置数据(XML格式),修改完毕后,再直接发给服务进行更新和存储。而在通信方式上,我们希望各个服务提供Web Service接口来实现配置的检索和更新。

但Web Service通常需要在Web Container(比如,tomcat, jboss)中实现,而我们不想把所有的服务都跑在tomcat里,于是想找到一种更加轻量级的方式。

今天偶然看到JSR311,进而发现在Java后台服务中内嵌grizzly(基于NIO的实现)和Jersey(Sun的JSR311参考实现)来提供Restful Web Service能力,是非常方便的。个人认为这种方式适用于后台Java程序的控制、配置和监视,其作用有些类似于JMX,但比实现JMX要简单的多(JSR311基于POJO)。

背景知识
Representational state transfer (REST) Web Service:
它是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。在目前三种主流的Web Service实现方案中,因为REST与SOAP和XML-RPC相比显的更加简洁,因此越来越多的Web Service开始采用REST风格设计和实现。

参考资料:http://en.wikipedia.org/wiki/Representational_State_Transfer

Jersey:
它是Sun对JSR311的官方参考实现,而JSR311是java中实现Restful Web Service的API规范(JSR311: JAX-RS: The Java API for RESTful Web Services)。JSR311有一个重要目标:使用注解(annotation)把POJO暴露成Web Service,这样就比较轻量级。

参考资料:https://jsr311.dev.java.net/nonav/releases/1.0/spec/index.html

Grizzly:
Grizzly于2004年诞生在GlassFish中,开始目的是要建构一个HTTP Web服务器,用来代替Tomcat的Coyote连接器和Sun WebServ er6.1。后来,Grizzly成为一种应用程序框架,专门解决编写成千上万用户访问服务器时候产生的各种问题。使用JAVA NIO作为基础,并隐藏其编程的复杂性。在本例中,我们将其用作内嵌的Servlet Container。

参考资料:https://grizzly.dev.java.net/

准备工作
首先,下载grizzly和jersey。其中,grizzly的下载地址为:http://download.java.net/maven/2/com/sun/grizzly/grizzly-servlet-webserver/1.9.18a/grizzly-servlet-webserver-1.9.18a.jar,jersey的下载地址为:http://download.java.net/maven/2/com/sun/jersey/jersey-archive/1.1.2-ea/jersey-archive-1.1.2-ea.zip

在Eclipse中建一个Java工程,名为jsr331,然后把下载的jersey-archive-1.1.2-ea.zip解压,将jersey-archive-1.1.2-ea/contribs、jersey-archive-1.1.2-ea/lib两个目录下的jar包,连同下载的grizzly-http-webserver-1.9.18a.jar都拷贝到jsr331工程下的lib目录,并加入到该工程的Build Path。(实测中,发现还需要引入一个包,下载地址:http://repository.jboss.org/maven2/org/jvnet/mimepull/1.2/mimepull-1.2.jar)

编写最简单的服务
JSR331把准备提供Web Service的类称为Resource class。Resource class是一个普通类(POJO),但是按照规范要求增加了特定的注解(annotation)。我们首先实现最简单的hello world服务。

在jinxfei.test.jsr311.service下,建立HelloService类,内容如下:

 

[java][/java] view plaincopy

  1. package jinxfei.test.jsr311.service;  
  2.   
  3. import javax.ws.rs.GET;  
  4. import javax.ws.rs.Path;  
  5. import javax.ws.rs.Produces;  
  6.   
  7. @Path(“/hello”)  
  8. public class HelloService {  
  9.     @GET   
  10.     @Produces(“text/plain”)  
  11.     public String helloWorld(){  
  12.         return ”Hello world!”;  
  13.     }     
  14. }  

 

代码中的注解(annotation)决定了程序发布成Web Service后的行为和特性。其中,HelloService类前面的@PATH,表明该Service的URL路径,这种类名前面带@PATH注解的类被称为Root Resource Class,因为他们决定了访问Service时URI中的第一级路径;@GET表示访问该服务使用HTTP GET方法;@Produces规定该服务返回结果的类型,这里的”text/plain”表名返回纯文本。

发布服务
实现服务类后,我们要启动一个内嵌的grizzly servlet container,并把HelloService发布到该Container中,这样就能通过HTTP协议访问该服务。Jersey提供了两种发布方式,标准的做法需要在web.xml中做配置,所以比较适用于部署在独立的Web Container下的应用,本文不做深入介绍,可参见:http://docs.sun.com/app/docs/doc/820-4867/6nga7f5o4?l=en&a=view。本例与grizzly整合,所以使用grizzly的工具类,通过代码进行部署配置。

在jinxfei.test.jsr311包下创建ServiceDeployer类,内容如下:

 

[java][/java] view plaincopy

  1. package jinxfei.test.jsr311;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.URI;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7. import javax.ws.rs.core.UriBuilder;  
  8. import com.sun.grizzly.http.SelectorThread;  
  9. import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;  
  10.   
  11. public class ServiceDeployer {  
  12.       
  13.     public static void main(String[] args) throws IOException {  
  14.         URI ServerURI=UriBuilder.fromUri(“http://localhost/”).port(9876).build();  
  15.         startServer(ServerURI);  
  16.         System.out.println(“服务已启动,请访问:”+ServerURI);  
  17.     }      
  18.       
  19.     protected static SelectorThread startServer(URI serverURI) throws IOException {  
  20.         final Map<String, String> initParams = new HashMap<String, String>();  
  21.         initParams.put(“com.sun.jersey.config.property.packages”,”jinxfei.test.jsr311.service”);  
  22.         System.out.println(“Grizzly 启动中…”);  
  23.         SelectorThread threadSelector = GrizzlyWebContainerFactory.create(serverURI, initParams);       
  24.         return threadSelector;  
  25.     }      
  26. }  

代码很简单,其中:initParams.put(“com.sun.jersey.config.property.packages” , “jinxfei.test.jsr311.service”); 这一行的第二个参数表明服务实现类所在的包名,系统会自动搜索做了注解的类并将其发布成服务。

 

在Eclipse中运行该类,控制台上打印“服务已启动”字样,表示系统启动成功,打开浏览器,输入:http://localhost:9876/hello,即可看到效果,如下图所示:

clip_image002

让功能再强一点点
接下来,我们要让服务能够接受参数,并根据参数打印不同的信息,最简单的就是回显(Echo)。为了实现这一功能,我们给HelloService类增加一个方法:

 

[java][/java] view plaincopy

  1. @POST @Path(“echo”)
  2.     @Consumes(“application/x-www-form-urlencoded”)
  3.     public String echo(@FormParam(“msg”) String message){
  4.         return ”Are you saying:”+message;
  5.     }

 

@POST表明该方法要用HTTP Post来访问,@Path表明访问该方法的相对路径是echo,@Consumes表明该方法处理HTTP Post请求中何种类型的数据。该方法参数中的注解@FormParam(“msg”)说明后面的“String message”参数取自表单提交数据中的msg。

由于该方法需要Post访问,且需要通过表单提交数据,所以我们创建一个test.htm,在其中写一个简单的Form:

[xhtml][/xhtml] view plaincopy

  1. <form action=”http://localhost:9876/hello/echo” method=”post”>
  2. <input type=”text” name=”msg”>
  3. <input type=”submit” value=”submit”>
  4. </form>

 

重启ServiceDeployer,然后在浏览器中打开test.htm,表单中输入任意信息:
clip_image004

然后点提交按钮,可以看到如下信息:
clip_image006

这说明HelloService已经提取了表单参数,并回显给用户。

深入学习
请参考官方资料:
JSR311规范:https://jsr311.dev.java.net/nonav/releases/1.0/spec/index.html
JSR311参考实现的主要特性:http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features

转自:http://blog.csdn.net/jinxfei/article/details/4714809