当前位置:  编程技术>php
本页文章导读:
    ▪挑战最棒的留言本的源码(五)       <html> <title>留言本</title> <body bgcolor=white> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <style type="text/css"> <!-- td {  font-family: "宋体", "serif"; font-s.........
    ▪使用网络地址转换实现多服务器负载均衡       摘要:本文探讨了分布式网络服务器使用的负载均衡技术及负载分配的策略,并基于网络地址转换在FreeBSD上实现了负载均衡网关,应用于我们的Internet网络服务器上,将负载分给多个服务器.........
    ▪挑战最棒的留言本的源码(四)       config.php文件 <?php  // 你的用户名和密码,以及数据库名,和表名,在这里一次定义!!! // 由于怕用户名和密码被别人通过浏览器看到,所以用了php的扩展名,这样通过浏览就看不到了!!!.      $.........

[1]挑战最棒的留言本的源码(五)
    来源: 互联网  发布时间: 2013-11-30
<html>
<title>留言本</title>
<body bgcolor=white>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">

<!--
td {  font-family: "宋体", "serif"; font-size: 9pt; font-weight: normal}
a:link {  text-decoration: none}
a:hover {  color: #999999}
a:visited {  text-decoration: none; font-weight: normal}
body {  font-family: "宋体", "serif"; font-size: 11pt}
tr {  font-family: "宋体", "serif"; font-size: 11pt}
.unnamed1 {  font-size: 9pt; font-weight: bold}
.p9 {  font-family: "宋体"; font-size: 11pt}
.unnamed2 {  font-size: 11pt}
-->
</style>
</head>
<h1><center><font color="green" size=7>留言信息</font></center></h1>

<?php  
      require('config.php');  
?>


<?php


$initial_record=0;
$sort_field='key_liuyan';
$sort_direction='DESC';

if (strlen($arr_request['initial_record']))
   {  
     $initial_record=$arr_request['initial_record'];
     $sort_field=$arr_request['sort_field'];
     $sort_direction=$arr_request['sort_direction'];

   }


$str_sql_all="select count(*) as number_of_records from $table_name ";

$result=mysql_db_query($db_name,$str_sql_all,$id_link);

if (!result)
   { affy_error_exit('SQL select execution has failed.');}

$record=@mysql_fetch_object($result);

$number_of_records=$record->number_of_records;

if (strlen($sort_field)==0)
  {
    $str_sql="select * from $table_name  
              limit $initial_record,$number_records_to_display ";

  }

else  
{

   $str_sql="select * from $table_name order by $sort_field $sort_direction
             limit $initial_record,$number_records_to_display ";
}


$result=mysql_db_query($db_name,$str_sql,$id_link);

if (!$result)
   { affy_error_exit('SQL select execution has failed.');}

$number_of_records_on_current_page=@mysql_num_rows($result);

if ($number_of_records<1)
  {  echo '<p>表中没有数据!<p>';}
else
  {
    $next_index=$initial_record+$number_records_to_display;

    if ($next_index>$number_of_records)
         $next_index=$number_of_records;

     

    $prev_index=$initial_record-$number_records_to_display;

    if ($prev_index<0)
       {
          $prev_index=0;
       }  


  }

echo "<center>";
echo "<table border=0><tr bgcolor=#f1f1f1><td width=24% align=left>";

if ($initial_record!=0)
   {
     $t1="initial_record=$prev_index";
     $sort="sort_field=$sort_field";
     $asc="sort_direction=$sort_direction";
     echo "<a href="/blog_article/$PHP_SELF/$asc/amp;$sort/amp;$t1.html">";
     echo "<<前 $number_records_to_display 条留言</a>";

   }

else
  {
     echo "|前面没有留言了";

  }

echo "</td><td width=52% align=center>";

    $t2=$initial_record+1;

    echo "本页显示第 <font color=green>$t2</font> 到 <font color=green>$next_index</font>
条留言,共<font color=blue>$number_of_records</font>条留言";

echo "</td><td width=24% align=right>";

if ($next_index!=$number_of_records)

  {
     $t1="initial_record=$next_index";
     $sort="sort_field=$sort_field";
     $asc="sort_direction=$sort_direction";
     echo "    <a href="/blog_article/$PHP_SELF/$asc/amp;$sort/amp;$t1.html">";
     echo "后 $number_records_to_display 条留言>></a>";
  }  
else
  {
     echo "后面没有留言了|";

  }

echo "</td></tr></table>";
echo "</center><p>";

?>

<center>

<a href=/blog_article/index.html><h4>[我也要留言]</h4></a>/index.html
<p>

<table border="0",width="95%" cellspacing="0" cellpadding="0">
<?php
for ($iindex=0;$iindex<$number_of_records_on_current_page;$iindex++)
{
$record=mysql_fetch_object($result);
require('display.inc');
}

?>
</table>
</center>

<p>
<?php  
echo "<center>";
echo "<table border=0><tr><td>";
echo "转到第";

if (($number_of_records % $number_records_to_display)==0)
   {
     $number_of_pages=$number_of_records / $number_records_to_display;

      
   }

else  
   {
     $number_of_pages=($number_of_records-($number_of_records % $number_records_to_display))/$number_records_to_display+1;

   }


     $sort="sort_field=$sort_field";
     $asc="sort_direction=$sort_direction";


for ($ii=1;$ii<=$number_of_pages;$ii++)

{
     $yeshu=($ii-1)*$number_records_to_display ;
     $t1="initial_record=$yeshu ";

     if ($initial_record!=$yeshu)
       {

         echo "<a href="/blog_article/$PHP_SELF/$asc/amp;$sort/amp;$t1.html">";
         echo "[ $ii ]</a>";
       }
     else
         echo "[ $ii ]";



}












echo "页  共<font color=blue> $number_of_pages </font>页";
echo "</td></tr></table>";
echo "</center><p>";

?>

<hr></hr>
<center>免费留言本由<a href="http://little.oso.com.cn" >小熊</a>提供技术支持</center>


</body>
</html>


【本文版权归作者与奥索网共同拥有,如需转载,请注明作者及出处】    

    
[2]使用网络地址转换实现多服务器负载均衡
    来源: 互联网  发布时间: 2013-11-30
摘要:本文探讨了分布式网络服务器使用的负载均衡技术及负载分配的策略,并基于网络地址转换在FreeBSD上实现了负载均衡网关,应用于我们的Internet网络服务器上,将负载分给多个服务器分担,以解决Internet服务器面临的大量并发访问造成的CPU或I/O的高负载问题。为了达到最佳的负载均衡效果,负载控制器需要根据各个服务器的当前CPU和I/O状态来分配负载,这就需要动态监视服务器的负载,并应用优化的负载分配策略,达到平均分配负载的目的。

关键字: 负载均衡,网络地址转换,FreeBSD


1. 引言

Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,服务器的处理和I/O能力成为了提供服务的瓶颈。由于单台服务器的性能总是有限的,必须采用多服务器和负载均衡技术才能满足大量并发访问的需要。

最早的负载均衡技术是通过DNS来实现的,在DNS中为多个地址配置同一个名字,因而查询这个名字的客户机将得到其中一个地址,从而使得不同的客户访问不同的服务器,达到负载均衡的目的[1]。DNS负载均衡是一种简单而有效的方法,但是它不能区分服务器的差异,也不能反映服务器的当前运行状态。

反向代理服务器可以将请求转发给内部Web服务器,如果代理服务器能够将请求均匀转发给多台内部服务器,就能达到负载均衡的目的[2]。反向代理方式下能应用优化的负载均衡策略,每次访问最空闲的内部服务器来提供服务。但是随着并发连接数量的增加,代理服务器本身的负载也变得非常大,最后反向代理服务器本身会成为服务的瓶颈。

支持负载均衡的地址转换网关中可以将一个外部IP地址映射为多个内部IP地址,对每次TCP连接请求动态使用其中一个内部地址,达到负载均衡的目的[3]。很多硬件厂商将这种技术集成在他们的交换机中,作为他们第四层交换的一种功能来实现,一般采用随机选择、根据服务器的连接数量或者响应时间进行选择的负载均衡策略来分配负载。然而硬件实现的负载控制器灵活性不强,不能支持更优化的负载均衡策略和更复杂的应用协议。

除了这三种负载均衡方式之外,有的协议内部支持与负载均衡相关的功能,例如HTTP协议中的重定向能力等,但它依赖于特定协议,因此使用范围有限。根据现有的这些负载均衡技术,我们选择了使用软件方式实现网络地址转换的负载均衡的方式,以弥补硬件负载均衡器的不灵活,并应用优化的均衡策略来实现后端服务器负载分担的最优状态。


2. 负载均衡策略

为了将负载均匀的分配给内部的多个服务器上,就需要应用一定的负载均衡策略。传统的负载均衡策略并没有考虑到服务请求的不同类型、后台服务器的不同能力以及随机选择造成的负载分配不均匀等问题。为了使得负载分配十分均匀,就要应用能够正确反映各个服务器CPU及I/O状态的负载均衡策略[4]。

客户发起的服务请求类型是多种多样的,按照对处理器、网络和I/O的资源要求,可以简单的将它们分为两个不同类别,以便应用不同的处理策略:



静态文档请求:例如普通的文本、图象等静态多媒体数据,它们对处理器负载影响不大,造成的磁盘I/O负载与文档的大小成正比,主要对网络I/O造成压力。


动态文档请求:更为常见的请求常常需要服务器预先进行处理,例如搜寻数据库、压缩解压缩多媒体文件等,这些请求需要相当大的处理器和磁盘I/O资源。


对于静态文档,每个服务进程占用大致相同的系统资源,因此就可以使用进程数来表示系统负载。而动态文档服务需要进行额外的处理,其占用的系统资源就超过处理静态请求,因此需要使用一个权重来表示。这样一个最简单的服务器负载表示公式就为:

其中L为服务器的负载,Ns为静态文档服务进程数,Nd为动态文档服务进程数,而a为每个动态文档服务相对于静态文档服务的权重,可以在10到100之间进行选择。

在这个公式中没有考虑服务器硬件的限制,当达到硬件限制的时候,由于资源紧张,服务器的负载就会明显增加。例如由于服务器内存大小的限制,一些进程就要被交换到硬盘上,使得系统负载迅速增加。考虑了系统硬件限制,则服务器的负载可以表示为:

新增加的参数 Ll表示这个服务器普通负荷的限度,它要根据每个服务器本身的硬件能力来设置。而b表示超出正常负载时用来限制分配给服务器任务的权重,应该设置为大于Ll的数值,以表示硬件限制作用。通常在一个服务器集群中,硬件设置越差的服务器这个权重越要设置的大,以避免在所有的服务器都超负载运行时,硬件最差的服务器反而负载最高。因此b是和本服务器硬件限制Ll成反比的,则b可以设置为:

Llmax为服务器集群中最高硬件配置的服务器的Ll值。当确定了每个服务器的负载之后,中心控制负载分配的服务器就能将负载正确的分发给最空闲的服务器,从而不会象其他的负载分配策略那样会导致负载分配不均匀的情况。


3. 实现方法及实验结果

我们的服务器系统由使用快速以太网连接起来的多台FreeBSD系统组成。每台后端服务器上运行一个守护进程来动态获得自己的负载状态,而使用FreeBSD实现的中心控制网关就通过这些守护进程刷新各个服务器的负载,以进行正确的负载分配。

3.1支持负载均衡的网关

在FreeBSD系统下,提供了divert接口以支持网络地址转换能力。IP数据包通过系统内核的ipfw过滤功能被发送到divert接口中,以便外部守护进程natd能接收原始数据包,处理之后再发回系统内核进行正常的IP分发[5]。

因此根据FreeBSD的地址转换结构,可以创建自己的网络地址转换守护进程,以支持负载均衡功能,这样就能将FreeBSD系统作为一个支持负载均衡的网关。由于它是软件实现的方式,很容易支持非标准的协议及应用优化的负载均衡策略,具备很大的灵活性。

3.2实验及分析

为测试这种实现的可用性,我们针对最常见的HTTP协议进行我们的测试实验。为了区分不同的请求种类,设计了三个不同类型的测试,以测试不同方面的性能。



CGI程序产生的动态文档:用于测试在服务器的处理能力的负载均衡状态。


小型静态文档:使用尺寸较小的静态文档,用于测试频繁连接下负载均衡的状态;


大型静态文档:使用较大的文档,测试磁盘及网络I/O的负载均衡状态;


测试结果以单台服务器每秒钟完成请求的性能为基准,显示使用多台服务器进行负载均衡时每秒种完成的请求数与基准请求次数的比率。



图1:负载均衡性能



从上图中的第一条曲线a是处理动态文档请求的,此时随着服务器数量的增加,其性能是成倍增加的;而第二条曲线b为处理小尺寸静态文档请求的,在使用三台服务器时性能改善就不明显了;而处理大尺寸静态文档请求的第三条曲线c则几乎没有发生性能变化。为了找到负载均衡系统达不到理想状态的原因,我们考察了服务器资源的利用率:

表1.服务器资源的利用率


处理类型
负载均衡网关
服务器1
服务器2
服务器3

a
53%
97%
95%
98%

b
76%
43%
39%
41%

c
94%
32%
31%
35%




从这个表中可以看出,当处理动态文档a时三台服务器都处于全速运行状态,负载被均匀分配,这是一种理想的状态。当处理静态文档类型b和c时,负载虽然被均匀分配给三台服务器,但每台服务器都没有处于全速运行状态。尤其在处理大尺寸文档时,负载均衡设备中的natd进程则占据了大部分处理资源。由于所有的网络流量都要经过它进行转换,因此在网络流量和并发连接数量相当大时,natd进程的负载就增加上去了。实验中使用不同数量的后端服务器时,流经负载均衡网关的实际网络带宽为:

表2:提供大尺寸文档时服务器集群的带宽


服务器数量
1台
2台
3台

网络速度(Kb/s)
10042.14
11015.10
11442.67




可以看出带宽限制在10MB/s左右,显然这是这个测试使用的负载均衡进程的带宽限制,事实上该程序使用了链表来维护网络地址转换的状态,这就大大限制了它的网络性能,通过提高硬件性能和改善算法,完全可以进一步提高其性能。


4.讨论

从上面的实验中可以看出,基于网络地址转换的负载均衡器可以有效的解决服务器端的CPU和磁盘I/O负载,然而负载均衡器本身的性能受网络I/O的限制,在一定硬件条件下具有一定的带宽限制,但可以通过改善算法和提高运行负载均衡程序的硬件性能,来提高这个带宽限制。同时也可以看出,不同的服务类型对不同的服务器资源进行占用,我们使用的负载衡量策略是使用同一个负载进行评估,这对于大多数条件是适合的,然而最好的办法是针对不同的资源,如CPU、磁盘I/O或网络I/O等,分别监视服务器负载,由中心控制器选择最合适的服务器分发客户请求。我们以后的工作将从这两个方面入手,完善这个负载均衡控制器。


参考文献:


[1] E.Kata,M.Butler, and R. McGrath. A scalable HTTP server: the ncsa prototype. Computer Networks and ISDN systems. 1994. Vol 27, P155-164

[2] Ralf S.Engelschall. Load Balancing Your Web Site. Web Techniques Magazine (http://www.WebTechniques.com), May 1998. vol.3, iss.5

[3] CICSO. LocalDirector Documents. http://www.cisco.com, 1997

[4] H.Zhu. T.Yang, Q.Zheng, D.Watson, O.H.Ibarra, andT.Smith, Adaptive load sharing for clustered digital library servers. Technical Report, CS, UCSB, 1998.

[5] FreeBSD core team. natd and divert manual pages. http://www.freebsd.org. 1995



Implement a load balancing gateway by NAT


Wang, Bo

NongYe Road 70, ZhengZhou, 450002, P.R.China

wb@email.online.ha.cn


Abstract: This paper investigates load balancing techniques and strategies, and implements a load balancing gateway based NAT for our Internet servers. The Internet servers involve the high load of CPU and I/O by simultaneous access requests, the symmetrical clustered servers can distribute the server load to solve the problem. To balance the load in the best way, the gateway distributes the load according to the status of server's CPU and I/O. The gateway must monitor every server's load and apply the best scheme to delivery every request, so it can provide the high performance for Internet services.

Keywords: load balancing, NAT, FreeBSD

    
[3]挑战最棒的留言本的源码(四)
    来源: 互联网  发布时间: 2013-11-30
config.php文件

<?php  
// 你的用户名和密码,以及数据库名,和表名,在这里一次定义!!!
// 由于怕用户名和密码被别人通过浏览器看到,所以用了php的扩展名,这样通过浏览就看不到了!!!.

     $username='your_name';          //用户名
     $password='your_password';          //密码

     $hostname='localhost';              //主机名,一般都为localhost     

     $db_name='your_db_name';           //数据库名
     $table_name='your_liuyan_table';        //存放留言的表名  

     $table_name_control='your_control_table';    //控制表名

     $number_records_to_display=5;  //每页显示的留言条数!


     $hang_zifu_number=50;  //换行的一行字符数!



// 连接数据库,在这里连好!!!

     $id_link=@mysql_connect($hostname,$username,$password);
     if (! $id_link) {
        affy_message("The connection to the local dtabase has failed.");}

// 处理参数,以后所有参数都可以通过 $arr_request['name']得到,不管是post的还是get的!!!

  $arr_request=array();
  if (count($HTTP_GET_VARS)) {
     while (list($key,$value)=each($HTTP_GET_VARS)) {
         $arr_request[strtolower($key)]=$value;
     }
  }

  if (count($HTTP_POST_VARS)) {
     while (list($key,$value)=each($HTTP_POST_VARS)) {
         $arr_request[strtolower($key)]=$value;
     }
  }

// 一些出错处理函数!

  function affy_footer() {
    echo '</body></html>';
  }

  function affy_header($title) {
    echo '<html><head><title>';
    echo "$title";
    echo '</title></head><body>';
  }

  function affy_message($msg) {
    echo '<table>';
    echo '<tr><td>';
    echo "$msg";
    echo '</td></tr>';
    echo '</table>';
  }

  function affy_error_exit($msg) {
      $errno = mysql_errno();
      $error = mysql_error();
      echo '<html><head><title>Error</title></head><body>';
      echo $msg;
      echo "<br>Error: ($errno) $error<br>";
      echo '</body></html>';
        exit();
  }

// 一些message处理函数!!!



//$test="2123.1.45.189";

function ip_question($msg)
{
//echo $msg;
//echo "<br>";
$ip=preg_split("/./",$msg);
$num=count($ip);
//echo $num;
$result="";
for($i=0;$i<$num-1;$i++)
{ $result=$result .$ip[$i].".";
  //echo $ip[$i];
  //echo "<br>";  

}
$result=$result ."XX";
return($result);  
}

//$result=ip_question($test);
//echo $result;



function add_blankto50($msg,$hang_zifu_number)
{
$num=strlen($msg);

$num_need=$hang_zifu_number-$num;
$str_suffix="";
for ($i=0;$i<$num_need;$i++)
{
  $str_suffix=$str_suffix." ";

}
//$num6=strlen($str_suffix);
//echo $num6;
//echo "<br>";

$pattern='/^(.*)/';
$replacement="\1$str_suffix";

$msg=preg_replace($pattern,$replacement,$msg);

return($msg);

}

function check_en_num($msg)
{
$pattern='/[x00-x7f]/';

preg_match_all($pattern,$msg,$matches);

$num2=count($matches[0]);

return($num2%2);

}

function short_one($msg)
{
$pattern='/.$/';
$replacement='';
$result=preg_replace($pattern,$replacement,$msg);

return($result);




}

function pian_question($msg)
{
$pattern="/'/";
$replacement="'";
$temp=preg_replace($pattern,$replacement,$msg);

$pattern="/\'/";
$replacement="'";
$result=preg_replace($pattern,$replacement,$temp);

return($result);    

}

function check_last($msg)
  {

$pattern='/.$/';

preg_match($pattern,$msg,$match);


if ($match[0]>'~')
  return(1);
else  
  return(0); // echo "英文";


}

//$num5=short_one($test);
//echo $num5;




function computer_message($msg,$hang_zifu_number)
{
$msg=pian_question($msg);

$arr_phone=preg_split("/n/",$msg);


$num=count($arr_phone);
//echo $num;
//echo "<br>";
//$num2=strlen($arr_phone[0]);
//echo $num2;
$first_line=1;

for ($i=0;$i<$num;$i++)
{
   while($str_num=strlen($arr_phone[$i])>$hang_zifu_number)
      {

         $first_line=0;
         $workstr=$arr_phone[$i];

          

         $pattern_pre50="/.{".$hang_zifu_number ."}/";

         preg_match_all($pattern_pre50,$workstr,$matches);
         $temp=$matches[0][0];

         if ((check_last($temp)==1)and(check_en_num($temp)==1))  //  ji shu and chinese
            {       
                   $hang_zifu_shortone=$hang_zifu_number-1;

                   $pattern_replace="/^.{".$hang_zifu_shortone ."}/";

                   $replacement='';
                   $arr_phone[$i]=preg_replace($pattern_replace,$replacement,$workstr);
                       // 前面49个处理完!

                   $temp=short_one($temp);  //从50个中减去一个.

             }  



         
         else   
            {

              $pattern_replace="/^.{".$hang_zifu_number ."}/";

              $replacement='';
              $arr_phone[$i]=preg_replace($pattern_replace,$replacement,$workstr);

            }  

  
         $message=$message . $temp."<br>";

      }

   if (($first_line==1)and(strlen($arr_phone[$i])<$hang_zifu_number))
     {

       $first_line=0;
       $temp_addblank=$arr_phone[$i];

       $temp_addblank=add_blankto50($temp_addblank,$hang_zifu_number);

       $message=$temp_addblank ."<br>";

     }

   else

       $message=$message .$arr_phone[$i]."<br>";


}
return($message);


}

//$num1=strlen($test);
//echo $num1;
//echo $test;

//echo "<br>";
//$mes=add_blankto50($test);
//$num9=strlen($mes);
//echo $num9;
//$result=ip_question($test);
//computer_message($test);
//echo $result;


function checkpass($passwd,$action,$db_name,$table_name_control,$id_link)
    {

      

     if ($action="/blog_article/delete/index.html")
        $str_sql="select value from $table_name_control where leibie='delete';";
     else if ($action="/blog_article/huifu/index.html")
        $str_sql="select value from $table_name_control where leibie='huifu';";
     else  
        echo "error";



     $result=mysql_db_query($db_name,$str_sql,$id_link);

     if (! $result) {
            affy_error_exit('SQL Execution has failed.');}


     $record= mysql_fetch_object($result);
    // echo $record->value;
    // echo "<br>";
    // echo $passwd;
    // echo "<br>";
     if ($record->value==$passwd)
        return(1);
     else
        return(0);    



   }

//$msg=computer_message($test,$hang_zifu_number);

//echo $msg;

?>


【本文版权归作者与奥索网共同拥有,如需转载,请注明作者及出处】    



    
最新技术文章:
▪PHP函数microtime()时间戳的定义与用法
▪PHP单一入口之apache配置内容
▪PHP数组排序方法总结(收藏)
▪php数组排序方法大全(脚本学堂整理奉献)
▪php数组排序的几个函数(附实例)
▪php二维数组排序(实例)
▪php根据键值对二维数组排序的小例子
▪php验证码(附截图)
▪php数组长度的获取方法(三个实例)
▪php获取数组长度的方法举例
▪判断php数组维度(php数组长度)的方法
▪php获取图片的exif信息的示例代码
▪PHP 数组key长度对性能的影响实例分析
▪php函数指定默认值的方法示例
▪php提交表单到当前页面、提交表单后页面重定...
▪php四舍五入的三种实现方法
▪php获得数组长度(元素个数)的方法
▪php日期函数的简单示例代码
▪php数学函数的简单示例代码
▪php字符串函数的简单示例代码
▪php文件下载代码(多浏览器兼容、支持中文文...
▪php实现文件下载、支持中文文件名的示例代码...
▪php文件下载(防止中文文件名乱码)的示例代码
▪解决PHP文件下载时中文文件名乱码的问题
▪php数组去重(一维、二维数组去重)的简单示例
▪php小数点后取两位的三种实现方法
▪php Redis 队列服务的简单示例
▪PHP导出excel时数字变为科学计数的解决方法
▪PHP数组根据值获取Key的简单示例
▪php数组去重的函数代码示例
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3