个人统计

用户名: 没楼可以吗
等级: 初来乍到
威望: 0
在线时间: 4 小时
日志总数: 337
评论数量: 13
访问次数: 182758
建立时间: 2004-04-28
RSS订阅       手机访问

博主资料

留言短消息 加为好友 收藏

用户ID:  41
昵称:  没楼可以吗
来自:  山东 聊城
年龄:  保密

日历

2018 - 2
    123
45678910
11121314151617
18192021222324
25262728   
«» 2018 - 2 «»

最近访问

日志分类

圈子信息

好友(0)

首页 前页 后页 尾页
1页,共 0 页

日志文章列表

2018年02月10日 09:47:01

[AS3]AS3.0中数字取整各种方法整理

int()去掉小数点
trace(int(3.14));  //输出3
trace(int(-3.14));  //输出-3
Math.round()方法:
Math.round()可以四舍五入对数字取整
trace(Math.round(39.88));  //输出40
trace(Math.round(58.33));  //输出58
Math.floor()方法:
Math.floor()可以向下取整
trace(Math.floor(39.88));  //输出39
trace(Math.floor(58.33));  //输出58
Math.ceil()方法:
Math.ceil()可以向上取整
trace(Math.ceil(39.88));    //输出40
trace(Math.ceil(58.33));    //输出59
toFixed()方法:
toFixed()方法四舍五入取指定位数的小数点,当其中参数为0时表示不留小数点
var temp:Number=3.1415926
//toFixed()中的参数就是需要取的小数位数,0表示不留小数点
var temp:Number=3.1415926
trace(temp.toFixed(2));  //输出3.14
trace(temp.toFixed(0));    //输出3
temp=18.888;
trace(temp.toFixed(0));    //输出19

Math.round()方法取小数位数:
比如说3.14159要精确到.001位,则先3.14159/.001,然后再Math.round(3.14159/.001),最后在把结果乘以需要精确的位数Math.round(3.14159/.001)*.001
trace(Math.round(3.14159/.001)*.001);  //输出3.142
trace(Math.round(3.14159/.01)*.01); //输出3.14
如果不想四舍五入,那直接改round()方法为floor()或者ceil()方法即可
toFixed()方法取小数位数:
直接指定toFixed()中的参数即可,比如要留两位小数,则toFixed(2)
var temp:Number=3.1415926
trace(temp.toFixed(1));    //输出3.1
temp=18.888;


无论刚入门的还是有一定AS3编程基础的,对Math类应该都不陌生了,但Math类的性能又知多少呢?请看下文吧。
  1、Math.floor()
通俗的讲这是一个取整函数。
  其实官方解释是
返回由参数 val 指定的数字或表达式的下限值。 下限值是小于等于指定数字或表达式的最接近的整数。
性能测试:
  var num:Number = Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  Math.floor(num);
}
trace(getTimer() - time);
// 结果:1865
var num:Number = Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  int(num);
}
trace(getTimer() - time);
// 结果:69
  结果很明显,int比floor快,可能大家就要说了,那Adobe傻X写个这样接口干什么?其实这就是我想说的对于floor的使用误区。
仔细看官方解释,其实floor不是一个真正我们所理解的取整函数,他是去找最接近自己,且比自己小或者等于的整数,那这是什么意思呢?
  var num:Number = - Math.PI;
trace(int(num));
trace(Math.floor(num));
// 结果1:-3
// 结果2:-4
  这个例子很明确表示,当目标数字是负数时,int和floor所得出的结果不一样。
  int()的官方解释
将给定数字值转换成整数值。 从小数点处截断十进制值。
相信看到这,你已经很明白了。
但是实际上,如果你这样去使用int(),跟floor输出的结果相同:
  var num:Number = - Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  if(num < 0){
    int(num) - 1;
  }else{
    int(num);
  }
}
trace(getTimer() - time);
// 结果:132

2、Math.pow()
对于这个方法,我也不知道说什么好了,先看性能测试吧:
  var a:int = 3;
var b:int = 4;
var c:int = 5;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  c * c == a * a + b * b;
}
trace(getTimer() - time);
// 结果:95
var a:int = 3;
var b:int = 4;
var c:int = 5;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  Math.pow(c,2) == Math.pow(a,2) + Math.pow(b,2);
}
trace(getTimer() - time);
// 结果:7999
  勾三股四弦五大家应该比较多,但是用"*"乘法运算和pow的性能比较那是非常明显啊。
难道大家又想说Adobe傻逼了?这儿我为它平反吧。
  var num:Number = Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  Math.pow(num,10000);
}
trace(getTimer() - time);
// 结果:6682
  先不说"*"乘法运算比pow快,就上面这段你能把它换算成使用"*"乘法运算吗?
而且pow其实是可以这样用的:(数学学得好都知道开方其实是可以转换成乘方来算的)
  trace(Math.pow(27,1/3));
trace(Math.pow(256,1/4));
trace(Math.pow(3125,1/5));
  而开方函数Adobe只提供了sqrt一个开平方根的接口(经测试Math.sqrt(9)比Math.pow(9,1/2)快,但开立方等就得靠pow了)。

3、Math.round()
这个方法跟floor一样的,先看性能测试:
  var num:int = Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  Math.round(num);
}
trace(getTimer() - time);
// 结果:1931
var num:int = Math.PI;
var length:int = 10000000;
var time:int = getTimer();
for(var i:int = 0; i < length; i ++){
  int(num + 0.5)
}
trace(getTimer() - time);
// 结果:68
  四舍五入其实加个0.5在取整,这样也是可以的,只不过用这个算法,存在跟第一个同样的问题,当目标数值为负时,两种方式结果不一样,需要加个判断,目标数值为负就把结果-1。

类别: 无分类 |  评论(0) |  浏览(13) |  收藏
2018年02月08日 16:23:24

关于wireshark的Header checksum出问题解决方案 在wireshark中显示是黑色的

包在wireshark中显示是黑色的,IP层显示错误:Header checksum: 0x0000 [incorrect, should be 0xffff (maybe caused by "IP checksum offload)].


首先解释Checksum offloading:
http://man.lupaworld.com/content/network/wireshark/c7.7.html


检验和计算可能由网络网络驱动,协议驱动,甚至是硬件完成。
例如:以太网传输硬件计算以太网循环容易校验,接受硬件验证这个校验。如果接受验证发现错误,Wireshark将不会接收到这个包,以太网硬件会直接丢弃这个包。
高层校验通常是由协议执行,并将完成后的包转交给硬件。
比较新的网络硬件可以执行一些高级功能,如IP检验和计算,这被成为checksum offloading。网络驱动不会计算校验和,只是简单将校验和字段留空或填入无效信息,交给硬件计算。
checksum offloading经常会导致混乱,因为网络包在检验和计算之前转交给Wireshark。Wireshark得到包的检验和字段是空的,必然会显示检验和错误,尽管这个包在从网络硬件发出的时候是带有校验和的。

Checksum offloading会引起混淆,让你屏幕上看到大量的[invalid]信息,引起你的反感。前面提到过,错误的检验和会导致包无法合并,更难进行包数据分析。
你可以采取两种方法避免Checksum offloading 问题
在驱动程序上关闭checksum offloading选项,如果可用的话。
通过首选项关闭Wireshark上特定协议的校验和验证。






关闭wireshark上特定协议的校验和验证方法:edit -> preferences -> protocols -> IPv4 -> validate the IPv4 checksum if possible 把对勾去掉。 这样会让wireshark中原来是黑色的BAD TCP不再显示黑色,但它仍是有问题的。。没有解决本质问题。。这个包的数据长度是0.


貌似应该采取第一个方法。这个人也遇到同样问题:http://#.com/3w417/item/d31e2f72294a1b46ef1e53ea
解决方法:
http://support.microsoft.com/kb/904946/en-us

To work around this problem, turn off checksum offloading on the network adapter. To do this, follow these steps:
1.Click Start, click Run, type regedit, and then click OK.
2.Locate and then click the following registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
3.In the right pane, make sure that the DisableTaskOffload registry entry exists. If this entry does not exist, follow these steps to add the entry:
a.On the Edit menu, point to New, and then click DWORD Value.
b.Type DisableTaskOffload, and then press ENTER.
4.Click DisableTaskOffload.
5.On the Edit menu, click Modify.
6.Type 1 in the Value data box, and then press ENTER.
7.Exit Registry Editor.
记得要重启机子。。

类别: 无分类 |  评论(0) |  浏览(18) |  收藏
2018年02月05日 16:56:17

no-cache 禁止缓存 禁止浏览器缓存- make sure web page is not cached

如何禁止浏览器缓存,网上搜到的解决方法都测试无效。

基本上全都是


Cache-Control: no-cache
Pragma: no-cache
Expires: 0
Google了一下,找到了解决方法。

设置response header 的效果就是 返回的时候一定是重新请求页面的。

Using PHP:

header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.Using Java Servlet, or Node.js:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.Using ASP.NET:

Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.Using ASP:

Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
Response.addHeader "Expires", "0" ' Proxies.Using Ruby on Rails, or Python on Flask:

response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response.headers["Pragma"] = "no-cache" # HTTP 1.0.
response.headers["Expires"] = "0" # Proxies.Using Google Go:

responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
responseWriter.Header().Set("Expires", "0") // Proxies.Using Apache .htaccess file:

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>Using HTML4:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
HTML meta tags vs HTTP response headers
根据SO上面的说法,
如果通过HTTP访问,HTTP response headers 是优先于 meta tags 的。但
是,第一次打开是通过HTTP访问的,而返回的时候是从本地读取的。


我在自己尝试的时候,发现这两个都需要设置 才能清除页面表单记录。Google浏览器 和 IE11测试通过,页面的记录消除。其他的浏览器未测试。(推测是因为上面的原因)
如果多次测试发现 页面表单的记录还在。


但是可以保证,只要写了HTTP response headers 返回的时候一定会重新请求。



部分代码如下
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>index.jsp</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" >
    <meta http-equiv="expires" content="0" >


应用
在防止表单重复提交的时候非常有用。

类别: 无分类 |  评论(0) |  浏览(13) |  收藏
2018年02月05日 14:42:42

简易nginx TCP反向代理设置 stream

nginx从1.9.0开始支持TCP反向代理,之前只支持HTTP。

为何需要?
为什么需要反向代理?主要是:

1.负载均衡
2.方便管控
比如我现在要更新后端服务器,如果不用负载均衡的话,在更新过程中,用户会出现无法连接服务器的情况,而一旦用了负载均衡,用户此时的连接请求将会分配到别的没在更新的后端服务器去,尽可能地确保了服务的可用性;再考虑这么种情况,我有多个服务器后端,那么就需要打开多个不同的监听端口,我需要在系统防火墙里做多个配置,如果它们与客户端的连接使用了SSL/TLS,那么得给它们各自配置证书,现在用了反向代理的话这些都简化了,服务器只需要打开一个对外监听端口,证书也只需要给反向代理配置好即可,就是我说的方便管控,当然了,还能方便的管控流量,设置一些额外的访问策略什么的。

那么反向代理的缺点是什么?我想如果后端多了起来,连接多了起来之后,对nginx来说是一个很大的挑战,毕竟TCP和HTTP不一样,TCP通常是“长连接”,要一直维持着的。到时候如果nginx撑不下去,就考虑用硬件负载均衡吧(不过听说这玩意儿不便宜)。

安装nginx
安装nginx的旧方法当然是去官网下载tar包,解压缩,configure,make……我在《HappyAA服务器部署笔记1》中有详细描述,现在我们不妨改进一下——用yum安装,这样更省事。我用的CentOS7的默认yum容器貌似并没有nginx,需要自己加装一下,其实很简单,改一下配置即可。在/etc/yum.repo.d底下创建文件nginx.repo,内容为:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1然后:

#yum install nginxnginx默认安装在/usr/sbin/nginx,检验下是否我们需要的nginx版本:

#/usr/sbin/nginx -v我安装的是1.9.11,没问题!再看看--with-stream和--with-stream_ssl_module这两个参数是否存在:

#/usr/sbin/nginx -V如果没有看到这两个参数,那就只好走老路来安装nginx了。

允许开机自动运行:

#systemctl enable nginx启动:

#systemctl start nginx对应着以前的service nginx start

查看nginx状态:

#systemctl status nginx对应着以前的service nginx status

发现了没有,使用yum安装管理起来也简单了。

nginx配置
编辑/etc/nginx/nginx.conf

stream{
    upstream backend{                                          1)
        hash $remote_addr consistent;
        server 127.0.0.1:7397 max_fails=3 fail_timeout=10s;    2)
        server 127.0.0.1:7398 max_fails=3 fail_timeout=10s;
    }

    server{
        listen 1268 ssl;                                      3)
        ssl_certificate    /home/guogangj/certs/cert1268.pem; 4)
        ssl_certificate_key  /home/guogangj/certs/key1268.pem; 5)
        ssl_session_cache    shared:SSL:10m;                  6)
        ssl_session_timeout  10m;                              7)
        ssl_ciphers  HIGH:!aNULL:!MD5;                        8)
        ssl_prefer_server_ciphers  on;                        9)
        proxy_connect_timeout 20s;                            10)
        proxy_timeout 5m;                                      11)
        proxy_pass backend;                                    12)
    }
}配置说明:

1) 设置一个叫“backend”的后端配置

2) 我有两个后端服务器,其中之一监听在7397端口,nginx尝试连接之,(10秒钟为判定失败的时长,这个我暂时也不太明白)最多失败3次,超过则不再重试

3) nginx监听在1268端口,使用SSL安全连接

注意:有必要的话,调整firewalld或iptables来允许这个端口的外部访问,对firewalld来说,可以添加这样的策略

firewall-cmd --zone=public --add-port=1268/tcp --permanent
firewall-cmd --reload查看一下firewalld的策略列表:

firewall-cmd --permanent --zone=public --list-all4) 所使用的X.509证书文件(PEM格式),对证书不熟悉的请参考《那些证书相关的玩意儿》,对于使用TCP协议的服务器端,其实是可以用自签的证书的,(如何生成自签证书,刚提到的文章里也有说明)你客户端“认”它就是了,反正我们的目的就是防范中间人攻击,不像做网站,我们得让浏览器“认”证书才行

5) 证书私钥文件

6) 设置SSL Session Cache使用“shared”方式更有利于提高资源的利用率,“SSL”是给缓存起的名字,你可以改成别的(这个名字如何用我现在不太清楚),“10m”为缓存大小(1M的缓存大约可以存放4000个session)

7) SSL Session的失效时间,默认5分钟,我设为10分钟

8) 指定SSL加密算法,照写即可(我一看数学就头大,所以至今仍未明白RSA的数学原理)

9) 更偏向于使用服务器的加密算法(这个我不太明白什么意思)

10) 指定nginx连接后端服务器超时的时间,指定为20秒

11) 距离上一次成功访问(连接或读写)后端服务器的时间超过了5分钟就判定为超时,断开此连接

12) 将TCP连接及数据收发转向叫“backend”的后端(这句话很关键)

完成
好像没啥好说的了,客户端连接1268这个端口完事。哦,对了,改好配置了别忘记重启下nginx:

#systemctl restart nginx

类别: 无分类 |  评论(0) |  浏览(16) |  收藏
2018年02月05日 14:30:14

nginx反向代理TCP,取RTMP流 NginxTCP/UDP代理 nginx_tcp_proxy_module  stream

nginx反向代理TCP,取RTMP流  nginx_tcp_proxy_module

nginx从1.9.0开始支持TCP反向代理,模块为stream,之前只支持HTTP。添加编译选项--with-stream。就可以使用stream这个模块。

一、说明
nginx默认只支持HTTP反向代理,如果需要支持TCP反向代理需添加tcp代理模块:nginx_tcp_proxy_module。

二、原料
1.nginx_tcp_proxy_module
下载地址:
wget https://github.com/yaoweibin/nginx_tcp_proxy_module/archive/master.zip

2.nginx源码
http://nginx.org/download/nginx-1.6.3.tar.gz

三、步骤
1.解压nginx


2.解压nginx_tcp_proxy_module
解压至/nginx-1.6.3/src/nginx_tcp_proxy_module

3.patch

cd /usr/wkdir/nginx-1.6.3

patch -p1 < src/nginx_tcp_proxy_module/tcp.patch
4.编译&安装

./configure --add-module=src/nginx_tcp_proxy_module-master如果报错缺少库,则安装相应库,如openssl

ubuntu下解决办法:

apt-get install openssl

apt-get install libssl-dev

centos下解决办法:

yum -y install openssl openssl-devel继续编译安装

make
make install5.修改配置文件
在nginx.conf中添加,模块指令是TCP,它是不属于HTTP框架内的,所以和HTTP{}同级别

tcp {
    upstream proxy_name {
        # simple round-robin
        server localhost:1935;#需要代理的端口

        #check interval=3000 rise=2 fall=5timeout=1000;
        #check interval=3000 rise=2 fall=5timeout=1000
        #check interval=3000 rise=2 fall=5timeout=1000
        #check_http_send "GET /HTTP/1.0\r\n\r\n";
        #check_http_expect_alive http_2xxhttp_3xx;
    }

    server {
        listen 8888; #代理8888端口

        proxy_pass proxy_name;
    }
}6.测试
启动nginx

./usr/local/nginx/sbin/nginx启动srs

./usr/local/srs/objs/srs -c conf/srs.conf使用ffmpeg推rtmp流到srs服务器(端口1935),然后通过vlc或者其他方式到代理端口8888获取rtmp流.

自测试成功!

=====================================

Nginx TCP/UDP 代理

这个模块可以实现基于TCP、UDP和Unix域的socket的协议的代理服务。这个 模块是在nginx-1.9 以后版本才添加的模块,如果要使用这个模块的话,要重新编译这个源代码,参考之前的的博客nginx安装,添加编译选项--with-stream。就可以使用 这个模块

配置基于TCP连接和UDP的数据报的反向代理
1.创建最顶层的stream {}块
stream{
....
}2.可以在stream {}块中创建一个或多个的server {}配置项
3.在每个server {}配置块中,要填写listen目标(IP+端口或是端口),如果是UDP协议还要包括 udp参数。在streamTCP是 默认 的协议。如果不进行 设置,系统默认是TCP协议 去 监听。
stream {
    server {
        listen 12345;
        ...
    }
    server {
        listen 53 udp;
        ...
    }
    ...
}4.利用proxy_pass选项定义被代理的 服务器或是上游组
stream {
    server {
        listen    12345;

        #TCP traffic will be proxied to the "stream_backend" upstream group
        proxy_pass stream_backend;
    }

    server {
        listen    12346;

        #TCP traffic will be proxied a proxied server
        proxy_pass backend.example.com:12346;
    }

    server {
        listen    53 udp;

        #UDP traffic will be proxied to the "dns_servers" upstream group
        proxy_pass dns_servers;
    }
    ...
}5.如果代理服务器有几个 网络接口,可以固定一个源IP和源端口去连接上游的服务器,可以选择proxy_bind字段去绑定的特定的IP和端口去连接上游的服务器(这个字段是可选的)
  stream {
    ...
    server {
        listen    127.0.0.1:12345;
        proxy_pass backend.example.com:12345;
        proxy_bind 127.0.0.1:12345;
    }
}这个 选项很可能需 要管理员用户的权限去 配置路由表截断来源被代理服务器的网络流量 。
+ 6.(这个字段是可选的),可以调整用来 传输代理服务器和上游组连接数据的双向内存缓存区的大小,根据实际传输的数据大小进行调整,如果传输数据比较少,这样做可以节省空间,如果数据量 大的可以减少socket read/write的次数

stream {
    ...
    server {
        listen            127.0.0.1:12345;
        proxy_pass        backend.example.com:12345;
        proxy_buffer_size 16k;
    }
}配置TCP和UDP负载均衡
1.在 top-level stream{}区块 里面可以添加一个或多个upstream{}的配置项,例如:stream_backend面向TCP servers和dns_server面向 的 是UDP_servers。
stream {
    upstream stream_backend {
        ...   
    }

    upstream dns_servers {
        ...   
    }
    ...
}注意:upstream group一定要在之前 定义proxy_pass。
+ 2.在upstream模块,使用server指令定义每一个upstream。包括它的域名或是IP地址加上必要的端口号。

stream {
    upstream stream_backend {
        server backend1.example.com:12345;
        server backend2.example.com:12345;
        server backend3.example.com:12346;
        ...
    }
    upstream dns_servers {
        server 192.168.136.130:53;
        server 192.168.136.131:53;
        ...
    }
    ...
}3.配置负载均衡的方法使用的是上游组,可以指定以下的一种方法:

round-robin(默认)
least-conn Nginx选择当前连接数最少的服务器
least_time Nginx选择最小延时时间和连接数最少的服务器。最小延时时间是基于以下参数进行运算的

connect-连接上游服务器的时间
first_byte 收到第一字节的最短时间
last_byte 收到服务器的响应
upstream stream_backend {
least_time first_byte;

server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12346;
}hash的方法,服务器基于用户定义值,例如:源IP地址($remote_addr)

upstream stream_backend {
    hash $remote_addr;

    server backend1.example.com:12345;
    server backend2.example.com:12345;
    server backend3.example.com:12346;
}4.(可选的)针对每一个上游服务器 设置固定参数,包括最大连接数,服务器的权重。
upstream stream_backend {
    hash  $remote_addr consistent;
    server backend1.example.com:12345 weight=5;
    server backend2.example.com:12345;
    server backend3.example.com:12346 max_conns=3;
}

    upstream dns_servers {
        least_conn;
        server 192.168.136.130:53;
        server 192.168.136.131:53;
        ...
    }

类别: 无分类 |  评论(0) |  浏览(14) |  收藏
2018年01月22日 09:36:02

GPG key retrieval failed: [Errno 14] Could not open/read file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

第一种是把这个key从这个源站copy过来,放到/etc/pki/rpm-gpg目录下

第二种是修改repo文件

vim /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 6 – $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

把gpgcheck=1改为gpgcheck=0

类别: 无分类 |  评论(0) |  浏览(26) |  收藏
2018年01月10日 10:21:30

[译]因扩展Object.prototype而引发Object.defineProperty不可用的一个问题

原文:http://d.hatena.ne.jp/teramako/20121129/p1
________________________________________
从ES-Discuss邮件列表中看到的.
Object.prototype.get = function(){};
var o = {};
Object.defineProperty(o, "hoge", { value: "OK" });
// TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified
问题描述就是:如果在Object.prototype上添加了名为get,set之类的属性的话,再执行Object.defineProperty()的时候就很有可能发生问题.为什么?
不应该在Object.prototype上添加的属性
下面给出的属性名最不应该添加在Object.prototype上
    get
    set
    value
    writable
为什么?
Object.defineProperty的第三个参数Descriptor是个对象,指定了所定义属性的属性描述符.属性描述符一共有两种.数据属性描述符(DataDescriptor)和访问器属性描述(AccessorDescriptor).
数据属性描述符对象上不能有get,set属性,访问器属性描述符对象上不能有value,writable属性.
执行defineProperty的时候,在判断属性描述符对象中某个属性是否存在时使用的内部方法是[[HasProperty]].[[HasProperty]]会在[[Prototype]]上寻找属性,也就找到了Object.prototype上定义的那些属性.如果使用[[GetOwnProperty]]来判断的话就不会有这样的问题了.
上例中的问题就是,get和value两个属性不能同时存在,否则会报错.
解决办法
创建一个没有原型的属性描述符对象:
var des = Object.create(null);
des.value = 123;
Object.defineProperty(obj,"key",des);
也可以使用非标准的魔法属性__proto__:
Object.defineProperty(obj, "key", {
  __proto__: null,
  value: 123
});
同样,Object.defineProperties()以及Object.create()的第二个参数中也有属性描述符对象,也有可能出现同样的问题.

类别: 无分类 |  评论(0) |  浏览(41) |  收藏
2018年01月08日 17:15:04

Unable to determine our source address: This computer has an invalid IP address: 0.0.0.0

Unable to determine our source address: This computer has an invalid IP address: 0.0.0.0


I'm thinking it might be your /etc/hosts file that is wrong.

try the command:
ping `hostname`
if it pings 127.0.0.1 then you are in trouble.

is your hostname on the line for localhost, something like
127.0.0.1 the-name-of-your-machine localhost

In that case I understand why vlc would get confused.

try changing it to:

127.0.0.1 localhost
the-ip-of-your-machine the-name-of-your-machine

then check with the following command:

ping `hostname`
this should ping your true IP address and not the dummy 127.0.0.1 one

=================================

Indeed, this problem isn't a vlc bug, but one of its dependency as live555.
There are two ways to fix the problem, as it will appear if you have a firewall that is closed by default.

- either using fixed ip from /etc/hosts like it was told before
- Or open the udp port 15947 of your firewall. (better if you have a dynamic ip attributed via dhcp).

类别: 无分类 |  评论(0) |  浏览(46) |  收藏
2017年11月14日 14:11:39

UTF-8编码的空格 0xC2 0xA0(194 160)问题

  前台的字符串传递到后台进行处理,发现了一个较诡异的问题:字符串中的一个空格(ASCII:32)被UTF-8编码之后变成了一个诡异的字符(ASCII:194 和 160的组合)!但在后台其表象还是空格。

  在UTF-8编码里面存在一个特殊的字符,其编码是“0xC2 0xA0”,转换成字符的时候表现为一个半角空格,跟一般的半角空格(ASCII 0x20)不同的是它的宽度不会被压缩,所以排版中常能用到它。但是GB2312、Unicode之类并没有这样的字符,所以转换后前台会显示为“?”号,只是显示为问号而不是真正的问号,所以无法被替换!

  对这两个看似相同的字符串进行一下转换可以确认:原始的字符串为:”#'  %$ ()_ -{}.b“  被转义后的字符串为:”#'  %$ ()_ -{}.b“ 【注:双引号不算,转换为byte数组之后可以看到,原来的是16个字节,后来的那个是17个字节:这就是 32 --> 194  160 的结果】

            string tmp1 = "#'  %$ ()_ -{}.b";
            string tmp2 = "#'  %$ ()_ -{}.b";
            byte[] o1 = Encoding.UTF8.GetBytes(tmp1);
            byte[] o2 = Encoding.UTF8.GetBytes(tmp2);  知道了这个原因之后,就好办了,写代码可以把194 和 160 的组合转换回去。程序(C#)如下所示:


        private string ChangeUTF8Space(string targetStr)
        {
            try
            {
                string currentStr = string.Empty;
                byte[] utf8Space = new byte[] { 0xc2, 0xa0 };
                string tempSpace = Encoding.GetEncoding("UTF-8").GetString(utf8Space);
                currentStr = targetStr.Replace(tempSpace, " ");
                return currentStr;
            }
            catch (Exception ex)
            {
                return targetStr;
            }
        }  更多的编码格式对照表可以看这篇文章:http://www.utf8-chartable.de/unicode-utf8-table.pl?utf8=dec

类别: 无分类 |  评论(0) |  浏览(72) |  收藏
2017年11月14日 13:52:26

Java 去除utf-8类型的空格的方法

问题产生

  最近遇到一个这样的问题,在生成的报文中,某个字段信息后面有一个空格,在代码中trim()下,它仍然存在。到底什么原因呢?

问题的根源

  经过多番查证,是由于utf-8中的特俗字符造成的。

  问题的根源,在于UTF-8这种编码里面,存在一个特殊的字符,其编码是“0xC2 0xA0”,转换成字符的时候,表现为一个空格,跟一般的半角空格(ASCII 0x20)一样,唯一的不同是它的宽度不会被压缩,因此比较多的被用于网页排版(如首行缩进之类)。而其他的编码方式如GB2312、Unicode之类并没有这样的字符,因此如果简单地进行编码转换,生成地GB2312/Unocode字符串中,这个字符就会被替换成为问号(ASCII ox3F)。

  使用UTF-8进行HTMLDecode的时候,对于语句开头的( ),就会被自动转换成为这个特殊的空格,可能是判断为放在开头的空格,一定是用来排版的。在转换为其他编码之前,这个特殊的空格受到的待遇与普通的半角空格是一致的,甚至也会被trim()去掉。

      因此,碰到这个问题的原因有两种:一种是在UTF-8编码下进行了转换,产生了这个字符;还有一种就是网页中直接采用了这个字符进行排版。

问题解决之法

C#代码如下:


      byte[] space = new byte[]{0xc2,0xa0};          string UTFSpace = Encoding.GetEncoding("UTF-8").GetString(space);          HtmlStr = HtmlStr.Replace(UTFSpace," ");

Java版:
        byte bytes[] = {(byte) 0xC2,(byte) 0xA0};
        String UTFSpace = new String(bytes,"utf-8");
        html = html.replaceAll(UTFSpace, " ");注意:  需要强调的是,替换之前不能进行编码转换,一定要继续使用UTF-8编码。如果已经转换成其他编码,那么错误就已经不可逆转了。没有办法再区分这个错误的问号和正常的问号之间的差别了。

类别: 无分类 |  评论(0) |  浏览(63) |  收藏
2017年11月14日 10:41:59

Configuring a DHCP Server

20.2. Configuring a DHCP Server
To configure a DHCP server, you must create the dhcpd.conf configuration file in the /etc/ directory. A sample file can be found at /usr/share/doc/dhcp-<version>/dhcpd.conf.sample.

DHCP also uses the file /var/lib/dhcpd/dhcpd.leases to store the client lease database. Refer to Section 20.2.2, “Lease Database” for more information.

20.2.1. Configuration File
The first step in configuring a DHCP server is to create the configuration file that stores the network information for the clients.Use this file to declare options and global options for client systems.

The configuration file can contain extra tabs or blank lines for easier formatting. Keywords are case-insensitive and lines beginning with a hash mark (#) are considered comments.

Two DNS update schemes are currently implemented — the ad-hoc DNS update mode and the interim DHCP-DNS interaction draft update mode. If and when these two are accepted as part of the Internet Engineering Task Force (IETF) standards process, there will be a third mode — the standard DNS update method. You must configure the DNS server for compatibility with these schemes. Version 3.0b2pl11 and previous versions used the ad-hoc mode; however, it has been deprecated. To keep the same behavior, add the following line to the top of the configuration file:

ddns-update-style ad-hoc;
To use the recommended mode, add the following line to the top of the configuration file:

ddns-update-style interim;
        Refer to the dhcpd.conf man page for details about the different modes.

There are two types of statements in the configuration file:

Parameters — State how to perform a task, whether to perform a task, or what network configuration options to send to the client.

Declarations — Describe the topology of the network, describe the clients, provide addresses for the clients, or apply a group of parameters to a group of declarations.

The parameters that start with the keyword option are reffered to as options. These options control DHCP options; whereas, parameters configure values that are not optional or control how the DHCP server behaves.

Parameters (including options) declared before a section enclosed in curly brackets ({ }) are considered global parameters. Global parameters apply to all the sections below it.

ImportantIf the configuration file is changed, the changes do not take effect until the DHCP daemon is restarted with the command service dhcpd restart.

TipInstead of changing a DHCP configuration file and restarting the service each time, using the omshell command provides an interactive way to connect to, query, and change the configuration of a DHCP server. By using omshell, all changes can be made while the server is running. For more information on omshell, refer to the omshell man page.

In Example 20.1, “Subnet Declaration”, the routers, subnet-mask, domain-name, domain-name-servers, and time-offset options are used for any host statements declared below it.

Additionally, a subnet can be declared, a subnet declaration must be included for every subnet in the network. If it is not, the DHCP server fails to start.

In this example, there are global options for every DHCP client in the subnet and a range declared. Clients are assigned an IP address within the range.

subnet 192.168.1.0 netmask 255.255.255.0 {
        option routers                  192.168.1.254;
        option subnet-mask              255.255.255.0;

        option domain-name              "example.com";
        option domain-name-servers      192.168.1.1;

        option time-offset              -18000;    # Eastern Standard Time

    range 192.168.1.10 192.168.1.100;
}
Example 20.1. Subnet Declaration

All subnets that share the same physical network should be declared within a shared-network declaration as shown in Example 20.2, “Shared-network Declaration”. Parameters within the shared-network, but outside the enclosed subnet declarations, are considered to be global parameters. The name of the shared-network must be a descriptive title for the network, such as using the title 'test-lab' to describe all the subnets in a test lab environment.

shared-network name {
    option domain-name              "test.redhat.com";
    option domain-name-servers      ns1.redhat.com, ns2.redhat.com;
    option routers                  192.168.0.254;
    more parameters for EXAMPLE shared-network
    subnet 192.168.1.0 netmask 255.255.252.0 {
        parameters for subnet
        range 192.168.1.1 192.168.1.254;
    }
    subnet 192.168.2.0 netmask 255.255.252.0 {
        parameters for subnet
        range 192.168.2.1 192.168.2.254;
    }
}
Example 20.2. Shared-network Declaration

As demonstrated in Example 20.3, “Group Declaration”, the group declaration is used to apply global parameters to a group of declarations. For example, shared networks, subnets, and hosts can be grouped.

group {
  option routers                  192.168.1.254;
  option subnet-mask              255.255.255.0;

  option domain-name              "example.com";
  option domain-name-servers      192.168.1.1;

  option time-offset              -18000;    # Eastern Standard Time

  host apex {
      option host-name "apex.example.com";
      hardware ethernet 00:A0:78:8E:9E:AA;
      fixed-address 192.168.1.4;
  }

  host raleigh {
      option host-name "raleigh.example.com";
      hardware ethernet 00:A1:DD:74:C3:F2;
      fixed-address 192.168.1.6;
  }
}
Example 20.3. Group Declaration

To configure a DHCP server that leases a dynamic IP address to a system within a subnet, modify Example 20.4, “Range Parameter” with your values. It declares a default lease time, maximum lease time, and network configuration values for the clients. This example assigns IP addresses in the range 192.168.1.10 and 192.168.1.100 to client systems.

default-lease-time 600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.254;
option domain-name-servers 192.168.1.1, 192.168.1.2;
option domain-name "example.com";

subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.10 192.168.1.100;
}
Example 20.4. Range Parameter

To assign an IP address to a client based on the MAC address of the network interface card, use the hardware ethernet parameter within a host declaration. As demonstrated in Example 20.5, “Static IP Address using DHCP”, the host apex declaration specifies that the network interface card with the MAC address 00:A0:78:8E:9E:AA always receives the IP address 192.168.1.4.

Note that the optional parameter host-name can also be used to assign a host name to the client.

host apex {
  option host-name "apex.example.com";
  hardware ethernet 00:A0:78:8E:9E:AA;
  fixed-address 192.168.1.4;
}
Example 20.5. Static IP Address using DHCP

TipThe sample configuration file provided can be used as a starting point and custom configuration options can be added to it. To copy it to the proper location, use the following command:

cp /usr/share/doc/dhcp-<version-number>/dhcpd.conf.sample /etc/dhcpd.conf
(where <version-number> is the DHCP version number).

For a complete list of option statements and what they do, refer to the dhcp-options man page.

20.2.2. Lease Database
On the DHCP server, the file /var/lib/dhcpd/dhcpd.leases stores the DHCP client lease database. Do not change this file. DHCP lease information for each recently assigned IP address is automatically stored in the lease database. The information includes the length of the lease, to whom the IP address has been assigned, the start and end dates for the lease, and the MAC address of the network interface card that was used to retrieve the lease.

All times in the lease database are in Coordinated Universal Time (UTC), not local time.

The lease database is recreated from time to time so that it is not too large. First, all known leases are saved in a temporary lease database. The dhcpd.leases file is renamed dhcpd.leases~ and the temporary lease database is written to dhcpd.leases.

The DHCP daemon could be killed or the system could crash after the lease database has been renamed to the backup file but before the new file has been written. If this happens, the dhcpd.leases file does not exist, but it is required to start the service. Do not create a new lease file. If you do, all old leases are lost which causes many problems. The correct solution is to rename the dhcpd.leases~ backup file to dhcpd.leases and then start the daemon.

20.2.3. Starting and Stopping the Server
ImportantWhen the DHCP server is started for the first time, it fails unless the dhcpd.leases file exists. Use the command touch /var/lib/dhcpd/dhcpd.leases to create the file if it does not exist.

If the same server is also running BIND as a DNS server, this step is not necessary, as starting the named service automatically checks for a dhcpd.leases file.

To start the DHCP service, use the command /sbin/service dhcpd start. To stop the DHCP server, use the command /sbin/service dhcpd stop.

By default, the DHCP service does not start at boot time. To configure the daemon to start automatically at boot time, refer to Chapter 15, Controlling Access to Services.

If more than one network interface is attached to the system, but the DHCP server should only be started on one of the interfaces, configure the DHCP server to start only on that device. In /etc/sysconfig/dhcpd, add the name of the interface to the list of DHCPDARGS:

# Command line options here
DHCPDARGS=eth0
This is useful for a firewall machine with two network cards. One network card can be configured as a DHCP client to retrieve an IP address to the Internet. The other network card can be used as a DHCP server for the internal network behind the firewall. Specifying only the network card connected to the internal network makes the system more secure because users can not connect to the daemon via the Internet.

Other command line options that can be specified in /etc/sysconfig/dhcpd include:

-p <portnum> — Specifies the UDP port number on which dhcpd should listen. The default is port 67. The DHCP server transmits responses to the DHCP clients at a port number one greater than the UDP port specified. For example, if the default port 67 is used, the server listens on port 67 for requests and responses to the client on port 68. If a port is specified here and the DHCP relay agent is used, the same port on which the DHCP relay agent should listen must be specified. Refer to Section 20.2.4, “DHCP Relay Agent” for details.

-f — Runs the daemon as a foreground process. This is mostly used for debugging.

-d — Logs the DHCP server daemon to the standard error descriptor. This is mostly used for debugging. If this is not specified, the log is written to /var/log/messages.

-cf <filename> — Specifies the location of the configuration file. The default location is /etc/dhcpd.conf.

-lf <filename> — Specifies the location of the lease database file. If a lease database file already exists, it is very important that the same file be used every time the DHCP server is started. It is strongly recommended that this option only be used for debugging purposes on non-production machines. The default location is /var/lib/dhcpd/dhcpd.leases.

-q — Do not print the entire copyright message when starting the daemon.

20.2.4. DHCP Relay Agent
The DHCP Relay Agent (dhcrelay) allows for the relay of DHCP and BOOTP requests from a subnet with no DHCP server on it to one or more DHCP servers on other subnets.

When a DHCP client requests information, the DHCP Relay Agent forwards the request to the list of DHCP servers specified when the DHCP Relay Agent is started. When a DHCP server returns a reply, the reply is broadcast or unicast on the network that sent the original request.

The DHCP Relay Agent listens for DHCP requests on all interfaces unless the interfaces are specified in /etc/sysconfig/dhcrelay with the INTERFACES directive.

To start the DHCP Relay Agent, use the command service dhcrelay start.


https://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-dhcp-configuring-server.html

类别: 无分类 |  评论(0) |  浏览(43) |  收藏
2017年11月14日 10:37:20

定位IO瓶颈的一些方法iostat (iotop工具具体查看IO负载主要是落在哪个进程上)

IO瓶颈往往是我们可能会忽略的地方(我们常会看top、free、netstat等等,但经常会忽略IO的负载情况),今天给大家详细分享一下如何确认一台服务器的IO负载是否到达了瓶颈,以及可能优化、定位的点。

先来看一台典型的IO密集型服务器的cpu统计图:

可以看到,CPU总使用率不高,平均1.3%,max到5.6%,虽然大部分都耗在了iowait上,但才百分之五左右,应该还没到瓶颈吧???
错了!这里要特别注意:iowait≠IO负载,要看真实的IO负载情况,一般使用iostat –x 命令:
$ iostat –x 1
avg-cpu:  %user  %nice %system %iowait  %steal  %idle
          0.04    0.00    0.04    4.99    0.00  94.92

Device:        rrqm/s  wrqm/s  r/s  w/s  rsec/s  wsec/s avgrq-sz avgqu-sz  await  svctm  %util
sda              0.00    81.00 104.00  4.00 13760.00  680.00  133.70    2.08  19.29  9.25  99.90
sda1              0.00    0.00  0.00  0.00    0.00    0.00    0.00    0.00    0.00  0.00  0.00
sda2              0.00    0.00  0.00  0.00    0.00    0.00    0.00    0.00    0.00  0.00  0.00
sda3              0.00    0.00  0.00  0.00    0.00    0.00    0.00    0.00    0.00  0.00  0.00
sda4              0.00    0.00  0.00  0.00    0.00    0.00    0.00    0.00    0.00  0.00  0.00
sda5              0.00    81.00 104.00  4.00 13760.00  680.00  133.70    2.08  19.29  9.25  99.90

这里重点指标是svctm和util这两列,man一下可以看到如下解释:
svctm
      The average service time (in milliseconds) for I/O requests that were issued to the device.
%util
      Percentage  of  CPU time during which I/O requests were issued to the device (bandwidth utilization for the device).Device saturation occurs when this value is close to 100%.

可以看到,svctm指的是“平均每次设备I/O操作的服务时间 (毫秒)”,而util指的是“一秒中I/O 操作的利用率,或者说一秒中有多少时间 I/O 队列是非空的。”
我们这里发现util已经接近100%,结合man的说明“Device saturation occurs when this value is close to 100%”可以知道其实目前这台服务器的IO已经到达瓶颈了。

那为什么最前面的cpu统计图的iowait项只有5.5%左右呢?因为这个iowait(也就是top里的wa%)指的是从整体来看,CPU等待IO的耗时占比:
wa -- iowait
Amount of time the CPU has been waiting for I/O to complete.
也就是说,CPU可能拿出一部分时间来等待IO完成(iowait),但从磁盘的角度看,磁盘的利用率已经满了(util%),这种情况下,CPU使用率可能不高,但是系统整体QPS已经上不去了,如果加大流量,会导致单次IO耗时的继续增加(因为IO请求都堵在队列里了),从而影响系统整体的处理性能。

确认了IO负载过高后,可以使用iotop工具具体查看IO负载主要是落在哪个进程上了。

那如何规避IO负载过高的问题呢?具体问题具体分析:
1. 如果你的服务器用来做日志分析,要避免多个crontab交叠执行导致多进程随机IO(参考:随机IO vs 顺序IO),避免定期的压缩、解压大日志(这种任务会造成某段时间的IO抖动)。
2. 如果是前端应用服务器,要避免程序频繁打本地日志、或者异常日志等。
3. 如果是存储服务(mysql、nosql),尽量将服务部署在单独的节点上,不要和其它服务共用,甚至服务本身做读写分离以降低读写压力;调优一些buffer参数以降低IO写的频率等等。另外还可以参考LevelDB这种将随机IO变顺序IO的经典方式。

参考资料:
http://oplinux.com/order/iostat.html
http://bencane.com/2012/08/06/troubleshooting-high-io-wait-in-linux/

类别: 无分类 |  评论(0) |  浏览(57) |  收藏
2017年10月17日 11:11:20

LINUX修改IP,永久生效命令方法

Linux修改IP 永久生效的办法就是修改配置文件:
先说临时生效的方法:
ifconfig eth0 192.168.10.24/24
ifconfig 网络设备名称 IP 地址/子网掩码位数

上面上方时临时生效。
下面是永久生效的方法:
修改配置文件:
vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
HWADDR=00:0C:29:5A:22:EF
TYPE=Ethernet
UUID=53c1c149-e126-443e-93fd-db592deb339e
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static #设置静态IP
IPADDR=192.168.10.24
NETMASK=255.255.255.0
BROADCAST=192.168.10.255
GATEWAY=192.168.10.2 #设置你自己的网关

临时+永久 就能达到不重启网卡是想IP地址永久生效了!


===================================

我是Linux程序员,我机器上的配置:
#vi /etc/sysconfig/network-scrips/ifcfg-eth0
auto lo
iface lo inet loopback

auto eth0 #意思是启用eth0
iface eth0 inet static #配置eth0为静态IP,也可以是动态的
address 192.168.2.151 #IP地址
netmask 255.255.255.0 #子网掩码
gateway 192.168.2.1 #网关

auto eth0:0 # 这个是假网卡,你可以不要这段
iface eth0:0 inet static
address 192.168.1.151
netmask 255.255.255.0
gateway 192.168.1.1
猜你一会儿可能还会遇到无法ping www.baidu.com的问题,配置这个文件就可以ping通了
#vi /etc/resolv.conf
nameserver 192.168.2.1 #这个地方就写网关地址就好了

类别: 无分类 |  评论(0) |  浏览(60) |  收藏
2017年10月16日 15:01:34

MySQL高可用架构之PXC实践

近期想对MySQL高可用架构做些研究并总结下来,本文是对PXC安装部署做个记录。
1、PXC简介
    官方介绍:
        Percona XtraDB Cluster is High Availability and Scalability solution for MySQL Users.
    主要特点:       
        Synchronous replication. Transaction either committed on all nodes or none.
        Multi-master replication. You can write to any node.
        Parallel applying events on slave. Real “parallel replication”.
        Automatic node provisioning.
        Data consistency. No more unsynchronized slaves.
    官方手册:
        https://www.percona.com/doc/percona-xtradb-cluster/5.6/index.html
2、PXC架构
    此图参考http://blog.csdn.net/signmem/article/details/17379427
   
  下图来自官方文档:
 

3、PXC安装部署
    本实验采用3节点,centos6.4_x86_64操作系统,PXC版本为5.6,galera-3。
  1)下载所需软件包
    cmake-2.8.12.2.tar.gz                  http://www.linuxfromscratch.org/blfs/view/7.5/general/cmake.html
    libev-4.22.tar.gz                          http://dist.schmorp.de/libev/Attic/
    Percona-XtraDB-Cluster-5.6.30-76.3.tar.gz    https://www.percona.com/downloads/Percona-XtraDB-Cluster-56/LATEST/
    DBD-mysql-4.033_02.tar.gz      http://www.filewatcher.com/d/FreeBSD/distfiles/Other/DBD-mysql-4.018.tar.gz.133427.html
    percona-xtrabackup-2.2.9.tar.gz     
    socat-2.0.0-b9.tar.gz                http://www.dest-unreach.org/socat/
    DBI-1.636.tar.gz                      http://www.cpan.org/modules/by-module/DBI/
    Percona-XtraDB-Cluster-5.6.30-25.16-raa929cb-el6-x86_64-bundle.tar 
    zlib-1.2.3.tar.gz                http://www.zlib.net/
  2)解压安装包
        for i in `ls`; do tar -xzvf $i; tar -xvf $i; done
  3)安装依赖包
    配置本地yum源:
    [root@node3 PXC]# mkdir /media/cdrom
    [root@node3 PXC]# mount CentOS-6.4-x86_64-bin-DVD1.iso  /media/cdrom/ -o loop
    [root@node3 PXC]# rm -rf  /etc/yum.repos.d/*.repo 
    [root@node3 PXC]# vi /etc/yum.repos.d/CentOS6.repo 
        [Base]
        name=CentOS6 ISO Base
        baseurl=file:///media/cdrom
        enabled=1
        gpgcheck=0
    依赖包检查安装:
    yum install -y git scons gcc g++ gcc-c++ openssl check cmake bison libaio libboost-all-dev libasio-dev libaio-dev libncurses5-dev libreadline-dev libpam-dev ncurses-devel
    rpm -q git scons gcc g++ gcc-c++ openssl check cmake bison libaio libboost-all-dev libasio-dev libaio-dev libncurses5-dev libreadline-dev  libpam-dev ncurses-devel

    cmake安装:
    [root@node3 PXC]# cd cmake-2.8.12.2
    [root@node3 cmake-2.8.12.2]# ./bootstrap
    [root@node3 cmake-2.8.12.2]# make -j 8
    [root@node3 cmake-2.8.12.2]# make install
    socat安装:
    [root@node3 PXC]# cd socat-2.0.0-b9
    [root@node3 socat-2.0.0-b9]# ./configure
    [root@node3 socat-2.0.0-b9]# make -j 8
    [root@node3 socat-2.0.0-b9]# make install
    [root@node3 socat-2.0.0-b9]# ln -s /usr/local/bin/socat  /usr/bin/
    DBI安装:
    [root@node3 PXC]# cd DBI-1.636
    [root@node3 DBI-1.636]# perl Makefile.PL
    [root@node3 DBI-1.636]# make -j 8
    [root@node3 DBI-1.636]# make install
    DBD安装:
    [root@node3 PXC]# cd DBD-mysql-4.033_02
    [root@node3 DBD-mysql-4.033_02]# perl Makefile.PL --mysql_config=/usr/local/mysql/bin/mysql_config
    [root@node3 DBD-mysql-4.033_02]# make -j 8
    [root@node3 DBD-mysql-4.033_02]# make install
    percona工具包安装:
    [root@node3 PXC]# for i in `rpm -qa |grep mysql`; do rpm -e $i --nodeps; done 
    [root@node3 PXC]# cd percona-xtrabackup-2.2.9
    [root@node3 percona-xtrabackup-2.2.9]# cmake ./
    [root@node3 percona-xtrabackup-2.2.9]# make -j 8
    [root@node3 percona-xtrabackup-2.2.9]# make install
    [root@node3 percona-xtrabackup-2.2.9]# ln -s /usr/local/xtrabackup/bin/* /usr/bin/
    [root@node3 PXC]# rpm -ivh Percona-XtraDB-Cluster-shared-56-5.6.30-25.16.1.el6.x86_64.rpm --nodeps
    [root@node3 PXC]# rpm -ivh Percona-XtraDB-Cluster-devel-56-5.6.30-25.16.1.el6.x86_64.rpm
    [root@node3 PXC]# rpm -ivh Percona-XtraDB-Cluster-galera-3-3.16-1.rhel6.x86_64.rpm --nodeps

    4)PXC数据库安装和配置
    Percona-XtraDB-Cluster安装:
    [root@node3 PXC]# tar -xzvf Percona-XtraDB-Cluster-5.6.30-76.3.tar.gz
    [root@node3 PXC]# useradd mysql -s /sbin/nologin
    [root@node3 PXC]# cd Percona-XtraDB-Cluster-5.6.30-76.3
    [root@node3 Percona-XtraDB-Cluster-5.6.30-76.3]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql  -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_MEMORY_STORAGE_ENGINE=1  -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/usr/local/mysql/data/ -DMYSQL_USER=mysql    -DENABLE_DOWNLOADS=1  -DWITH_WSREP=1 -DWITH_EDITLINE=0
    [root@node3 Percona-XtraDB-Cluster-5.6.30-76.3]# make -j 4
    [root@node3 Percona-XtraDB-Cluster-5.6.30-76.3]# make install
    初始化数据库:
    [root@node3 PXC]# cd /usr/local/mysql
    [root@node3 mysql]# ./scripts/mysql_install_db --user=mysql  --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data/
    [root@node3 mysql]# cp support-files/mysql.server  /etc/init.d/mysqld
    [root@node3 mysql]# chkconfig --add mysqld
    [root@node3 mysql]# chkconfig mysqld on
    [root@node3 mysql]# chown -R mysql.mysql /usr/local/mysql
    [root@node3 mysql]# vi ~/.bash_profile
        PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
    [root@node3 mysql]# source ~/.bash_profile
    配置my.cnf
    node1节点:
[client]
socket=/usr/local/mysql/mysql.sock
[mysqld]
datadir=/usr/local/mysql/data
user=mysql
log-bin=mysql-binlog
binlog_format=ROW
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address=gcomm://IP1,IP2,IP3
wsrep_slave_threads=2
wsrep_cluster_name=my_centos_cluster
#wsrep_sst_method=rsync
#wsrep_sst_method=mysqldump
wsrep_sst_method=xtrabackup
wsrep_node_name=node1
wsrep_node_address=IP1
wsrep_sst_auth="repuser:userpasswd"

    node2节点
[client]
socket=/usr/local/mysql/mysql.sock
[mysqld]
datadir=/usr/local/mysql/data
user=mysql
log-bin=mysql-binlog
binlog_format=ROW
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address=gcomm://IP1,IP2,IP3
wsrep_slave_threads=2
wsrep_cluster_name=my_centos_cluster
#wsrep_sst_method=rsync
#wsrep_sst_method=mysqldump
wsrep_sst_method=xtrabackup
wsrep_node_name=node2
wsrep_node_address=IP2
wsrep_sst_auth="repuser:userpasswd"



    node3节点
[client]
socket=/usr/local/mysql/mysql.sock
[mysqld]
datadir=/usr/local/mysql/data
user=mysql
log-bin=mysql-binlog
binlog_format=ROW
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address=gcomm://IP1,IP2,IP3
wsrep_slave_threads=2
wsrep_cluster_name=my_centos_cluster
#wsrep_sst_method=rsync
#wsrep_sst_method=mysqldump
wsrep_sst_method=xtrabackup
wsrep_node_name=node3
wsrep_node_address=IP3
wsrep_sst_auth="repuser:userpasswd"
    启动Node1数据库
    [root@node1 mysql]# service mysqld bootstrap-pxc
    创建PXC复制账户并授权
    mysql> show status like 'wsrep%';
    mysql> delete from mysql.user where user ='';
    mysql> delete from mysql.user where user ='root' and host='::1';
    mysql> delete from mysql.user where user ='root' and host='node1';
    mysql> delete from mysql.user where user ='root' and host='127.0.0.1';
    mysql> CREATE USER 'repuser'@'localhost' IDENTIFIED BY 'userpasswd';
    mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'repuser'@'localhost';
    mysql> FLUSH PRIVILEGES;
    启动node2节点数据库
    (先将my.cnf的wsrep_sst_method参数值设置为rsync,完成节点加入后,可以设置回xtrabackup,重启数据库)
    [root@node2 mysql]# service mysqld start
    启动node3节点数据库
    (先将my.cnf的wsrep_sst_method参数值设置为rsync,完成节点加入后,可以设置回xtrabackup,重启数据库)
    [root@node3 mysql]# service mysqld start
4、安装错误信息以及解决方案
    错误信息01:
    [root@node3 PXC]# rpm -ivh Percona-XtraDB-Cluster-shared-56-5.6.30-25.16.1.el6.x86_64.rpm
    warning: Percona-XtraDB-Cluster-shared-56-5.6.30-25.16.1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY
    error: Failed dependencies:
            libcrypto.so.10(libcrypto.so.10)(64bit) is needed by Percona-XtraDB-Cluster-shared-56-1:5.6.30-25.16.1.el6.x86_64
            libssl.so.10(libssl.so.10)(64bit) is needed by Percona-XtraDB-Cluster-shared-56-1:5.6.30-25.16.1.el6.x86
    解决方案:
    检查是否安装了对应的openssl,如果已安装并找到相应的库文件,可以忽略依赖关系。
    [root@node3 PXC]# rpm -qa |grep openssl
    openssl-1.0.0-27.el6.x86_64
    openssl098e-0.9.8e-17.el6.centos.2.x86_64
    openssl-devel-1.0.0-27.el6.x86_64
    [root@node3 PXC]# ls -l /usr/lib64/libssl.so.10
    lrwxrwxrwx. 1 root root 15 Aug 17 17:41 /usr/lib64/libssl.so.10 -> libssl.so.1.0.0
    [root@node3 PXC]# rpm -ivh Percona-XtraDB-Cluster-shared-56-5.6.30-25.16.1.el6.x86_64.rpm --nodeps

    错误信息02:
    which: no socat in (/usr/sbin:/sbin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/mysql/bin)
    WSREP_SST: [ERROR] socat not found in path: /usr/sbin:/sbin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/mysql/bin (20160818 14:45:08.903)
    2016-08-18 14:45:08 7131 [ERROR] WSREP: Failed to read 'ready ' from: wsrep_sst_xtrabackup --role 'joiner' --address 'IP2' --datadir '/usr/local/mysql/data/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '7131'  ''
            Read: '(null)'
    2016-08-18 14:45:08 7131 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup --role 'joiner' --address 'IP2' --datadir '/usr/local/mysql/data/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '7131'  '' : 2 (No such file or directory)
    2016-08-18 14:45:08 7131 [ERROR] WSREP: Failed to prepare for 'xtrabackup' SST. Unrecoverable.
    2016-08-18 14:45:08 7131 [ERROR] Aborting
    解决方案:
    安装socat 并做软连 ln -s /usr/local/bin/socat  /usr/bin/

    错误信息03:
    node2节点
    tar: This does not look like a tar archive
    tar: Exiting with failure status due to previous errors
    WSREP_SST: [ERROR] Error while getting data from donor node:  exit codes: 0 2 (20160818 15:32:52.658)
    WSREP_SST: [ERROR] Cleanup after exit with status:32 (20160818 15:32:52.660)
    2016-08-18 15:32:52 12825 [Warning] WSREP: 0.0 (node1): State transfer to 1.0 (node2) failed: -22 (Invalid argument)
    2016-08-18 15:32:52 12825 [ERROR] WSREP: gcs/src/gcs_group.cpp:gcs_group_handle_join_msg():736: Will never receive state. Need to abort
    2016-08-18 15:32:52 12825 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup --role 'joiner' --address 'IP2' --datadir '/usr/local/mysql/data/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '12825'  '' : 32 (Broken pipe)
    2016-08-18 15:32:52 12825 [ERROR] WSREP: Failed to read uuid:seqno from joiner script.
    2016-08-18 15:32:52 12825 [ERROR] WSREP: SST script aborted with error 32 (Broken pipe)
    2016-08-18 15:32:52 12825 [ERROR] WSREP: SST failed: 32 (Broken pipe)
    2016-08-18 15:32:52 12825 [ERROR] Aborting
    node1节点

    160818 15:32:52  innobackupex: Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_file=/etc/my.cnf;mysql_read_default_group=xtrabackup;mysql_socket=/usr/local/mysql/mysql.sock' as 'repuser'  (using password: YES).
    innobackupex: got a fatal error with the following stacktrace: at /usr/bin/innobackupex line 2999
            main::mysql_connect('abort_on_error', 1) called at /usr/bin/innobackupex line 1539
    innobackupex: Error: Failed to connect to MySQL server as DBD::mysql module is not installed at /usr/bin/innobackupex line 2999.

    解决方案:
    安装DBI和DBD软件包,并且需要安装Percona-XtraDB-Cluster-shared-56-5.6.30-25.16.1.el6.x86_64和Percona-XtraDB-Cluster-devel-56-5.6.30-25.16.1.el6.x86_64

    错误信息04:

    WSREP_SST: [ERROR] xtrabackup process ended without creating '/usr/local/mysql/data//xtrabackup_galera_info' (20160818 16:30:33.614)

    WSREP_SST: [ERROR] Cleanup after exit with status:32 (20160818 16:30:33.628)
    WSREP_SST: [INFO] Removing the sst_in_progress file (20160818 16:30:33.629)
    2016-08-18 16:30:33 15314 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup --role 'joiner' --address 'IP2' --datadir '/usr/local/mysql/data/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '15314'  '' : 32 (Broken pipe)
    2016-08-18 16:30:33 15314 [ERROR] WSREP: Failed to read uuid:seqno from joiner script.
    2016-08-18 16:30:33 15314 [ERROR] WSREP: SST script aborted with error 32 (Broken pipe)
    2016-08-18 16:30:33 15314 [ERROR] WSREP: SST failed: 32 (Broken pipe)
    2016-08-18 16:30:33 15314 [ERROR] Aborting

    解决方案:
    初始数据同步问题,可以先通过设置node2,node3参数wsrep_sst_method=rsync完成数据同步,然后再改回wsrep_sst_method=xtrabackup即可。

5、附录
    1)openssl源码安装
    wget ftp://ftp.openssl.org/source/openssl-1.0.0c.tar.gz
    tar -zxf openssl-1.0.0c.tar.gz
    cd openssl-1.0.0c/
    ./config  --prefix=/usr/local --openssldir=/usr/local/ssl
    make && make install
    ./config shared --prefix=/usr/local --openssldir=/usr/local/ssl
    make clean
    make && make install
    2)gcc升级
    需要四个安装包,分别是:boost_1_60_0.tar.gz  gcc-4.8.0.tar.gz  gmp-5.1.3.tar.gz  mpc-1.0.3.tar.gz  mpfr-3.1.3.tar.gz
    gmp安装
    ./configure  --prefix=/usr/local/gmp
    make
    make test
    make install
    mpfr安装
    ./configure --with-gmp-include=/usr/local/gmp/include  --with-gmp-lib=/usr/local/gmp/lib --prefix=/usr/local/mpfr
    make
    make install
    mpc安装
    ./configure --with-mpfr-include=/usr/local/mpfr/include  --with-mpfr-lib=/usr/local/mpfr/lib --with-gmp-include=/usr/local/gmp/include --with-gmp-lib=/usr/local/gmp/lib
    make
    make install
    gcc安装
    ./configure --with-gmp-include=/usr/local/gmp/include --with-gmp-lib=/usr/local/gmp/lib --with-mpfr-include=/usr/local/mpfr/include --with-mpfr-lib=/usr/local/mpfr/lib --with-mpc-include=/usr/local/mpc/include --with-mpc-lib=/usr/local/mpc/lib --enable-languages=c,c++ --enable-threads=posix --disable-multilib
    3)参考命令
        show status like  '%wsrep%';
        show variables like 'wsrep_sst_method';

类别: 无分类 |  评论(0) |  浏览(62) |  收藏
2017年10月16日 14:57:54

试试Linux下的ip命令,ifconfig已经过时了

Linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者。使用ip命令,只需一个命令,你就能很轻松地执行一些网络管理任务。ifconfig是net-tools中已被废弃使用的一个命令,许多年前就已经没有维护了。iproute2套件里提供了许多增强功能的命令,ip命令即是其中之一。

CentOS的ifconfig, route以及ip指令的实战应用 http://www.linuxidc.com/Linux/2013-05/83956.htm

CentOS安装后ifconfig 无法显示网卡 http://www.linuxidc.com/Linux/2013-04/82573.htm

CentOS的ifconfig, route以及ip指令的实战应用 http://www.linuxidc.com/Linux/2013-05/83956.htm

ifconfig: command not found  http://www.linuxidc.com/Linux/2012-07/64703.htm

CentOS 6.2下ifconfig输出网口和ip http://www.linuxidc.com/Linux/2012-06/63672.htm

要安装ip,请点击这里下载iproute2套装工具 。不过,大多数Linux发行版已经预装了iproute2工具。

你也可以使用git命令来下载最新源代码来编译:

$ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/shemminger/iproute2.git

设置和删除Ip地址
要给你的机器设置一个IP地址,可以使用下列ip命令:

$ sudo ip addr add 192.168.0.193/24 dev wlan0
请注意IP地址要有一个后缀,比如/24。这种用法用于在无类域内路由选择(CIDR)中来显示所用的子网掩码。在这个例子中,子网掩码是255.255.255.0。

在你按照上述方式设置好IP地址后,需要查看是否已经生效。

$ ip addr show wlan0


你也可以使用相同的方式来删除IP地址,只需用del代替add。

$ sudo ip addr del192.168.0.193/24 dev wlan0


列出路由表条目
ip命令的路由对象的参数还可以帮助你查看网络中的路由数据,并设置你的路由表。第一个条目是默认的路由条目,你可以随意改动它。

在这个例子中,有几个路由条目。这个结果显示有几个设备通过不同的网络接口连接起来。它们包括WIFI、以太网和一个点对点连接。

$ ip route show


假设现在你有一个IP地址,你需要知道路由包从哪里来。可以使用下面的路由选项(译注:列出了路由所使用的接口等):

$ ip route get10.42.0.47

更改默认路由
要更改默认路由,使用下面ip命令:

1.$ sudo ip route add default via 192.168.0.196


显示网络统计数据
使用ip命令还可以显示不同网络接口的统计数据。
ip -s link

当你需要获取一个特定网络接口的信息时,在网络接口名字后面添加选项ls即可。使用多个选项-s会给你这个特定接口更详细的信息。特别是在排除网络连接故障时,这会非常有用。

1.$ ip -s -s link ls p2p1


ARP条目
地址解析协议(ARP)用于将一个IP地址转换成它对应的物理地址,也就是通常所说的MAC地址。使用ip命令的neigh或者neighbour选项,你可以查看接入你所在的局域网的设备的MAC地址。

1.$ ip neighbour


监控netlink消息
也可以使用ip命令查看netlink消息。monitor选项允许你查看网络设备的状态。比如,所在局域网的一台电脑根据它的状态可以被分类成REACHABLE或者STALE。使用下面的命令:

1.$ ip monitor all


激活和停止网络接口

你可以使用ip命令的up和down选项来激某个特定的接口,就像ifconfig的用法一样。

在这个例子中,当ppp0接口被激活和在它被停止和再次激活之后,你可以看到相应的路由表条目。这个接口可能是wlan0或者eth0。将ppp0更改为你可用的任意接口即可。

1.$ sudo ip link set ppp0 down
2.$ sudo ip link set ppp0 up


获取帮助
当你陷入困境,不知道某一个特定的选项怎么用的时候,你可以使用help选项。man页面并不会提供许多关于如何使用ip选项的信息,因此这里就是获取帮助的地方。

比如,想知道关于route选项更多的信息:

1.$ ip route help

小结
对于网络管理员们和所有的Linux使用者们,ip命令是必备工具。是时候抛弃ifconfig命令了,特别是当你写脚本时。

类别: 无分类 |  评论(0) |  浏览(56) |  收藏
2017年10月16日 13:58:05

InnoDB log file 设置多大合适?

简介:
    数据库的东西,往往一个参数就牵涉N多知识点。所以简单的说一下。大家都知道innodb是支持事务的存储引擎。事务的四个特性ACID即原子性(atomicity),一致性(consistency),隔离性(isolation),持久性(durability)。其中原子性,一致性,持久性通过redo log 和 undo来实现。redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。 当事务提交时,必须先将该事务的所有日志写入到重做日志文件(redo log)进行持久化(当然先写到日志缓冲区,而不是直接写文件,关于什么时候刷新到磁盘文件,是一个比较复杂的问题,同学们自行查阅资料),待事务提交操作才算完成。innodb的redo log是顺序I/O,所以设置合适的值能够大大提高数据库性能。那么是不是设置的越大越好呢?

设置的太小:当一个日志文件写满后,innodb会自动切换到另外一个日志文件,而且会触发数据库的检查点(Checkpoint),这会导致innodb缓存脏页的小批量刷新,会明显降低innodb的性能。

设置的太大:设置很大以后减少了checkpoint,并且由于redo log是顺序I/O,大大提高了I/O性能。但是如果数据库意外出现了问题,比如意外宕机,那么需要重放日志并且恢复已经提交的事务,如果日志很大,那么将会导致恢复时间很长。甚至到我们不能接受的程度。

那么我们如何估算log file该设置为多大?通常我们可以通过观察show status中innodb_os_log_written状态变量来查看innodb对日志文件写出了多少数据。一个好用的经验是,查看10-100秒间隔的数字,然后记录峰值。可以用这个判断日志缓冲是否设置的正好。例如,若看到峰值是每秒写100kb数据到日志,那么1MB的日志缓冲已经足够了。也可以使用这个衡量标准来决定日志文件设置多大会比较好。如果峰值是100KB/s,那么256M的日志文件足够存储至少2560秒的日志记录。一般来说,日志文件的全部大小,应该足够容纳服务器一个小时的活动内容。

下面看实际的测试(由于是虚拟机,所以使用sysbench模拟据量写入,生产环境选择数据库最繁忙的时候测试):

[root@yayun-mysql-server ~]# sysbench --test=oltp --oltp-table-size=100000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=180 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare
    1.首先计算innodb每分钟产生的日志量:
(root@yayun-mysql-server) [(none)]>pager grep sequence
PAGER set to 'grep sequence'
(root@yayun-mysql-server) [(none)]>show engine innodb status\G select sleep(60); show engine innodb status\G
Log sequence number 6377275259
1 row in set (0.00 sec)

1 row in set (1 min 0.00 sec)

Log sequence number 6403945555
1 row in set (0.00 sec)

(root@yayun-mysql-server) [(none)]>nopager
PAGER set to stdout
(root@yayun-mysql-server) [(none)]>select (6403945555 - 6377275259) / 1024 / 1024 as MB_per_min;                   
+-------------+
| MB_per_min  |
+-------------+
| 25.43477631 |
+-------------+
1 row in set (0.02 sec)

(root@yayun-mysql-server) [(none)]>注意Log sequence number,这是写入事务日志的总字节数。所以,现在你可以看到每分钟有多少MB日志写入(这里的技术适用于所有版本的MySQL,在5.0及更高版本,你可以从SHOW GLOBAL STATUS的输出看Innodb_os_log_written的值) 。

通过计算后得到每分钟有25M的日志写入。

根据经验法则。通常我们设置redo log size足够大,能够容纳1个小时的日志写入量。

1小时日志写入量=25M * 60=1500M,大约等于1.5G。由于默认有两个日志重做日志文件ib_logfile0和ib_logfile1。在日志组中的每个重做日志文件的大小一致,并以循环的方式写入。innodb存储引擎先写重做日志文件0,当达到文件的最后时,会切换到重做日志1,并checkpoint。以此循环。

所以我们可以大约设置innodb_log_file_size=800M。注意:在innodb1.2.x版本之前,重做日志文件总的大小不得大于等于4G,而1.2.x版本将该限制扩大到了521G。

innodb_log_file_size = 800M[root@yayun-mysql-server mysql]# du -sh ib_logfile*
801M    ib_logfile0
801M    ib_logfile1
[root@yayun-mysql-server mysql]# 对于innodb 1.2.x版本之前如果设置大于4G则报错


[root@yayun-mysql-server mysql]# tail -n 10 yayun-mysql-server.err 
140511  1:01:15 InnoDB: Completed initialization of buffer pool
140511  1:01:15 InnoDB: Error: combined size of log files must be < 4 GB
140511  1:01:15 [ERROR] Plugin 'InnoDB' init function returned error.
140511  1:01:15 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
140511  1:01:15 [ERROR] Failed to initialize plugins.
140511  1:01:15 [ERROR] Aborting

140511  1:01:15 [Note] /usr/local/mysql/bin/mysqld: Shutdown complete

140511 01:01:15 mysqld_safe mysqld from pid file /data/mysql/yayun-mysql-server.pid ended
[root@yayun-mysql-server mysql]# 而innodb 1.2.x以后版本则不会:


[root@yayun-mysql-server mysql5.6]# tail -f yayun-mysql-server.err   
2014-05-11 01:06:47 5205 [Note] InnoDB: Using Linux native AIO
2014-05-11 01:06:47 5205 [Note] InnoDB: Initializing buffer pool, size = 128.0M
2014-05-11 01:06:47 5205 [Note] InnoDB: Completed initialization of buffer pool
2014-05-11 01:06:47 5205 [Note] InnoDB: Highest supported file format is Barracuda.
2014-05-11 01:06:47 5205 [Warning] InnoDB: Resizing redo log from 2*3072 to 2*327680 pages, LSN=1085681253
2014-05-11 01:06:47 5205 [Warning] InnoDB: Starting to delete and rewrite log files.
2014-05-11 01:06:47 5205 [Note] InnoDB: Setting log file ./ib_logfile101 size to 5120 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100
2014-05-11 01:12:40 5205 [Note] InnoDB: Setting log file ./ib_logfile1 size to 5120 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100

类别: 无分类 |  评论(0) |  浏览(59) |  收藏
2017年10月16日 13:54:50

mysql的innodb中事务日志ib_logfile

事务日志或称redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节
开启几组日志来服务于当前mysql数据库,mysql采用顺序,循环写方式,每开启一个事务时,
会把一些相关信息记录事务日志中(记录对数据文件数据修改的物理位置或叫做偏移量);
作用:在系统崩溃重启时,作事务重做;在系统正常时,每次checkpoint时间点,会将之前写入事务
应用到数据文件中。
引入一个问题:在m/s环境中,innodb写完ib_logfile后,服务异常关闭,会不会主库能用ib_logfile恢复数据,而
binlog没写导致从库同步时少少这个事务?从而导致主从不一致;
redo日志写入方式:
1.ib_logfile写入当前事务更新数据,并标上事务准备trx_prepare
2.写入bin-log
3.ib_logfile当前事务提交提交trx_commit
恢复方式:
如果ib_logfile已经写入事务准备,那么在恢复过程中,会依据bin-log中该事务是否存在恢复数据。
假设:
1)结束后异常,因没有写入bin-log,从库不会同步这个事务,主库上,重启时,在恢复日志中这个
事务没有commit,即rollback这个事务.
2)结束后异常,这会bin-log已经写入,从库会同步这个事务。主库依据恢复日志和bin-log,也正常恢复此事务
综上描述:bin-log写入完成,主从会正常完成事务;bin-log没有写入,主从库rollback事务;不会出现主从库不一致问题.
相关参数(全局&静态):
innodb_log_buffer_size
innodb_log_file_size
innodb_log_files_in_group
innodb_log_group_home_dir
innodb_flush_log_at_trx_commit
innodb_log_buffer_size:事务日志缓存区,可设置1M~8M,默认8M,延迟事务日志写入磁盘,
把事务日志缓存区想象形如"漏斗"状,会不停向磁盘记录缓存的日志记录,而何时写入通过参数
innodb_flush_log_at_trx_commit控制,稍后解释,启用大的事务日志缓存,可以将完整运行大事
务日志,暂时存放在事务缓存区中,不必(事务提交前)写入磁盘保存,同时也起到节约磁盘空间占用;
innodb_log_file_size:控制事务日志ib_logfile的大小,范围5MB~4G;所有事务日志ib_logfile0+
ib_logfile1+..累加大小不能超过4G,事务日志大,checkpoint会少,节省磁盘IO,但是大的事务日
志意味着数据库crash时,恢复起来较慢.
引入问题:修改该参数大小,导致ib_logfile文件的大小和之前存在的文件大小不匹配
解决方式:在干净关闭数据库情况下,删除ib_logfile,而后重启数据库,会自行创建该文件;
innodb_log_files_in_group:DB中设置几组事务日志,默认是2;
innodb_log_group_home_dir:事务日志存放目录,不设置,ib_logfile0...存在在数据文件目录下
innodb_flush_log_at_trx_commit:控制事务日志何时写盘和刷盘,安全递增:0,2,1
事务缓存区:log_buffer;
0:每秒一次事务缓存区刷新到文件系统,同时文件系统到磁盘同步,但是事务提交时,不会触发log_buffer到文件系统同步;
2:每次事务提交时,会把事务缓存区日志刷新到文件系统中去,且每秒文件系统到磁盘同步;
1:每次事务提交时刷新到磁盘,最安全;
适用环境:
0:磁盘IO能力有限,安全方便较差,无复制或复制延迟可以接受,如日志性业务,mysql损坏丢失1s事务数据;
2:数据安全性有要求,可以丢失一点事务日志,复制延迟也可以接受,OS损坏时才可能丢失数据;
1:数据安全性要求非常高,且磁盘IO能力足够支持业务,如充值消费,敏感业务;





转自:http://blog.itpub.net/26855487/viewspace-776041/

类别: 无分类 |  评论(0) |  浏览(58) |  收藏
2017年10月15日 13:53:43

[高危]使用存在漏洞的JQuery版本解决方法

    最近在使用360网站安全检测时,提示“[高危]使用存在漏洞的JQuery版本”,导致网站安全检测直接标红,分数大打折扣,相信不少的站长朋友都遇到了该问题吧!很多网站长都在纠结如何去除JQuery版本漏洞?有的站长说法是替换新的JQuery版本,但是并无任何效果。下面电脑我帮您小编将给大家分享解决方法,让你的网站重新赢得360网站安全检测好评分。

步骤方法:
    其实方法很简单,直接去除JQuery版本的版本号,比如,电脑我帮您小编使用的是:jquery-3.2.1.min.js,则将FTP网站JS文件下的:jquery-3.2.1.min.js重命名为:jquery.min.js,最后将网站模板文件里面所有调用jquery的代码,修改为:jquery.min.js就OK了。
    不过大家还需要做的一个步骤就是重新登录360网站安全,点击:立即检测或者快速检测,就可以看到360网站安全检测已经不会再提示[高危]使用存在漏洞的JQuery版本了。

类别: 无分类 |  评论(0) |  浏览(70) |  收藏
2017年10月15日 10:15:26

jQuery版本升级踩坑大全

背景
--------------------------------------------------------------------------------
jQuery想必各个web工程师都再熟悉不过了,不过现如今很多网站还采用了很古老的jQuery版本。其实如果早期版本使用不当,可能会有DOMXSS漏洞,非常建议升级到jQuery 1.9.x或以上版本。前段时间我就主导了这件事情,把公司里我们组负责的项目jQuery版本从1.4.2升级到了jQuery 1.11.3。jQuery官方也为类似升级工作提供了jQuery Migrate插件。
言归正传。
坑从何处来
--------------------------------------------------------------------------------
jQuery 1.11.3是1.x时代的最后一个版本(作者更新:2016年1月8日,jQuery 1.12.0上线,jQuery 1.11.3不再是1.x时代最后一个版本了),由于我的部门项目已经有一定年头了,当时还是采用的jQuery 1.4.2,这次升级步子迈得算是比较大。早期时候jQuery的很多写法,在新版本中已经被废弃,亦或者有些不规范的写法,当时版本还能支持,但是现在已经不支持。更糟糕的情况是,新版本还支持,但是功能已经和以前不一样了……这种情况连个错都不会报,需要深入到代码逻辑里面去看。
jQuery官方推荐了jQuery Migrate 库来解决jQuery升级问题。不过一直采用这个库终究不是长久之计,开发中建议使用jQuery Migrate的开发版,可以在浏览器控制台上打印出来不兼容的地方详细信息。需要注意的是开发中一定要使用jQuery Migrate的开发版,因为压缩版的是不会在控制台给出警告的……把jQuery Migrate的库紧跟在jQuery库后面引用即可:
<script src="<path>/<to>/jquery-1.11.3.js"></script>
<script src="<path>/<to>/jquery-migrate-1.2.1.js"></script>
等升级完毕,确定没问题了之后,再将jQuery Migrate库去掉就可以了。根据个人经验,下面我把坑分成 常见坑,少见坑两类来论述。
常见坑
--------------------------------------------------------------------------------
1. 使用了被废弃的jQuery.fn.live方法
jQuery Migrate库对此错误也在控制台有相应的警告:
JQMIGRATE: jQuery.fn.live() is deprecated
live方法原本的作用是设置事件代理,该方法在jQuery 1.7之后就不推荐使用了,取代之的是jQuery.fn.on函数。他们的接口分别是:
$(selector).live('click', function(){/* some code */});
$(selector).on('click', [selector,] function(){/* some code */});
乍一看,中括号里面的参数可以省略掉,俩函数不是一模一样么?于是天真地把函数名live直接替换成on,大部分时候,这么做好像没有引起任何异常。但是如果在你调用on函数的时候,前面的$(selector)在当前的网页上根本不匹配任何元素(该元素可能是后面的代码才加到DOM里的),那是不会绑定成功的。事实上,live函数将$(selector)代理到了document元素上,这个元素是肯定存在的,所以不会出现类似情况。正确的替换方法应该是:
$(selector).live('click', function(){/* some code */}); 替换为
$(document).on('click', selector, function(){/* some code */});
2. 使用了被废弃的jQuery.fn.die方法
jQuery Migrate对此错误的警告是:
JQMIGRATE: jQuery.fn.die() is deprecated
这个方法和前面的live刚好反过来,取消事件处理函数的绑定。新版本中应该使用off函数代替之,替换方式类似。
3. 使用了被废弃的jQuery.fn.toggle函数
jQuery Migrate对此错误的警告是:
JQMIGRATE: jQuery.fn.toggle(handler, handler...) is deprecated
早期jQuery中名字叫toggle的函数有两个,一个是用于控制元素的显示和隐藏,这个用途的函数目前jQuery中依旧存在;另一个就是上面提到的被废弃的toggle函数,它用于绑定至少两个函数到同一个元素,点击该元素的时候两个函数交替着执行。这两个同名函数功能相差甚远,为了不引起误导,在jQuery 1.8中就不再建议使用了。替换的方式是把两个函数合并成一个函数的if-else两个区段,然后自己设置一个boolean变量,控制每次点击时应该执行哪个区段即可。
4. 使用了被废弃的jQuery.browser属性
jQuery Migrate对此错误的警告是:
JQMIGRATE: jQuery.browser is deprecated
在前端开发中我们经常要根据不同的浏览器版本做出不同的处理,jQuery.browser本来是通过浏览器的userAgent字段来提取浏览器相关信息的。新版本中已经将其废弃,而是建议使用特征检测的方法去判断,并且给了一个Modernizr库作为推荐。不过,改成这个库可能改动成本有点大,如果你还是想沿用jQuery.browser的思路的话,可以自己去实现一下它。例如,判断是不是IE浏览器,可以用
/msie/.test(navigator.userAgent.toLowerCase());
即自己手动获取userAgent字段,并且做一个正则表达式匹配。其他浏览器思路类似,都是对navigator.userAgent做一个正则匹配。
5. $(html)格式书写错误
在jQuery Migrate中,出现以下三种警告中的任何一种,都是属于这个错误:
JQMIGRATE: $(html) HTML strings must start with '<' character
JQMIGRATE: $(html) HTML text after last tag is ignored
JQMIGRATE: HTML string cannot start with a '#' character
这个错误还是蛮值得注意的,因为我们文章开头所说的jQuery低版本有XSS漏洞,其实就是和这个错误有关系。在javascript中我们经常会直接将一段html格式的字符串写在jQuery引用里面,比如$('<div></div>')。按照新版本的jQuery要求,这段html格式的字符串必须是以左尖括号(小于号)开头,其他字符都不可以。以下几种写法,都是错误的:
$(" <div></div>"); //错误,字符串最开头有一个空格,不是以小于号'<'开头的
$("<div></div>test"); //不标准,html标签结束后后面还有多余的"test",它会被忽略
$("#<div></div>); //错误,以井号开头并且后面并不是一个css选择器
这一点在书写的时候注意一下就可以了,其实还是很容易避免的。其中第三种错误其实就不仅仅是警告了,jQuery会直接抛出一个错误,停止javascript代码的继续执行。一般情况以井号开头,例如$("#test"),其实就是一个普通的选择器,但是上面例子中后面又夹杂着html字符串,这会被jQuery判断为潜在的XSS攻击。
6. jQuery.fn.attr方法的错误使用(这是个非常易犯的错误!)
jQuery Migrate中,关于attr方法的警告有以下这些:
JQMIGRATE: jQuery.fn.attr('value', val) no longer sets properties
JQMIGRATE: jQuery.fn.attr('value') no longer gets properties
JQMIGRATE: jQuery.fn.attr('checked') may use property instead of attribute
JQMIGRATE: jQuery.fn.attr( props, pass ) is deprecated
实践中我发现,早期写的代码里面,获取一个input输入表单的值时,是怎么获取的呢?$('input').attr('value');又是怎么设置的呢?$('input').attr('value', 'helloworld')。这在新版本中都是不正确的!正确的做法应该是
$('input').val(); //获取input表单现在所输入的值
$('input').val('helloworld'); //设置input表单输入的值
到底是获取还是设置,只取决于调用val方法时有没有带着参数。
如果你想手动设置单选框(例如<input type="radio" >)被选中,应该怎么设置呢?老的代码里面可能会看到这样 $('input').attr('checked', true)或者$('input').attr('checked', 'checked')。这些现在也都是不正确的!正确的做法应该是
$('input').prop('checked', true); //把单选框设为选中状态
$('input').prop('checked'); //获取单选框是不是被选中了,返回true或false
这是从jQuery 1.6版本开始使用的写法。如果设置disabled和selected属性,也是使用prop方法。那到底什么时候使用attr方法呢?两者的区别是:prop设置的是某元素固有的属性,而attr设置的是写在html标签上的自定义属性。举个例子:
<input type="checkbox" checked="checked" haha="hello" >
var v1 = $('input').prop("checked"); //返回true/false,是否被选中,随状态改变而改变
var v2 = $('input').attr("checked"); //返回"checked",这是你设置在标签上的,不会变
var v3 = $('input').attr("haha"); //返回"hello",自定义属性
var v4 = $('input').prop("haha"); //返回undefined,根本没有这个固有属性
上面提到的第四个错误,jQuery.fn.attr(props, pass) is deprecated这个警告在真实项目中从未见到过,看了一下源码,触发该警告的jQuery写法很少见,可忽略。
7. 向$.parseJSON传入了非法的参数
在jQuery Migrate中,该错误产生如下警告
JQMIGRATE: jQuery.parseJSON requires a valid JSON string
jQuery之所以改这个接口,是为了和浏览器自带的JSON.parse接口对齐,从jQuery 1.9开始生效。这个问题常见于AJAX接收服务端返回值的时候。服务端可能返回一个空字符串,这时候调用该接口会产生错误。必须向$.parseJSON传入合法的JSON字符串。修正方法如下:
var v1 = $.parseJSON(str); 替换为
var v1 = $.parseJSON( str ? str : "null" );
8. 使用了被废弃的'hover'事件字符串
在jQuery Migrate中该错误产生如下警告
JQMIGRATE: 'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'
在注册事件处理函数时,'hover'以前可以看作是'mouseenter mouseleave'两个事件的别称。目前已经将该别称去掉了,所以代码中请用'mouseenter mouseleave'替换之。
9. jQuery.fn.andSelf已经被替换,不能再使用
jQuery Migrate中是这样的警告:
JQMIGRATE: jQuery.fn.andSelf() replaced by jQuery.fn.addBack()
两个函数功能是完全一样的,可以直接替换。
以上,就是在jQuery升级中常见的问题,当然,本着精益求精的精神,我们还是需要研究一下不常见的问题是什么样子的。需要指出的是:下面的问题在我的实际项目中从来没有碰到过,比较少见,但也无法保证一定不会出现在你的项目中,仅供感兴趣的程序员们参考吧。
少见坑
--------------------------------------------------------------------------------
1. jQuery不兼容浏览器的怪异模式
这个错误的触发方式非常简单,直接把html页面最顶端的<!DOCTYPE html>标签删掉就可以了。浏览器怪异模式是为了兼容老古董网页而设计的,详情可参考这篇文章:链接。我想现在的WEB程序员应该不会傻到不写DOCTYPE,也很少使用这种模式下的浏览器吧。
jQuery Migrate展示的错误警告如下:
2. AJAX全局事件必须绑定到document节点上
jQuery Migrate中的警告如下:
JQMIGRATE: AJAX events should be attached to document: ajaxStart
jQuery中AJAX全局事件包括如下接口ajaxStart, ajaxStop, ajaxSend, ajaxComplete, ajaxError, ajaxSuccess。因为这些事件使用的比较少,所以也归在少见坑当中。从jQuery 1.9开始,这些事件只能绑定到$(document)上。改正方法如下(摘自jQuery官网):
$("#status").ajaxStart(function(){ $(this).text("Ajax started"); }); 修改为
$(document).ajaxStart(function(){ $("#status").text("Ajax started"); });
3. IE6/7/8浏览器不支持修改input表单的type属性
在jQuery Migrate中是这样的警告:
JQMIGRATE: Can't change the 'type' of an input or button in IE 6/7/8
改变input的表单的type属性,你可以直接把文本框改成单选框,改成多选框等等。虽然我感觉这是一种并不算优雅的行为,但是很多浏览器都是支持这么做的,除了IE6/7/8。建议在实际中也是少用这个功能为好。
4. 使用了被移除的$.clean, $.event.handle, $.attrFn, $.fn.data('events'), jQuery.event.trigger属性与方法
在jQuery Migrate中是这样的警告:
JQMIGRATE: jQuery.clean() is deprecated
JQMIGRATE: jQuery.event.handle is undocumented and deprecated
JQMIGRATE: jQuery.attrFn is deprecated
JQMIGRATE: Use of jQuery.fn.data('events') is deprecated
JQMIGRATE: Global events are undocumented and deprecated
如果你在自己的代码中使用过这五个接口,那确实是仔细研究过jQuery源代码的高人啊。因为这五个接口从来没有出现在jQuery的官方文档中,并且有些在后续版本中已经删除,可谓来无影去无踪。看源代码的话在早期版本有机会找到他们的存在,但是并不建议使用。建议采用其他方法实现相应的功能。什么?你不知道这五个函数是什么功能?那最好了,你现在也不需要知道了……
5. 使用了过时的$.sub()方法
jQuery Migrate中对本问题的警告如下:
JQMIGRATE: jQuery.sub() is deprecated
这个接口非常简单,不接受任何参数。它用来创建一个jQuery的副本。该方法在jQuery 1.7版本开始就已经不再使用。
6. 使用了过时的jQuery.fn.error方法
jQuery Migrate中对本问题的警告如下:
JQMIGRATE: jQuery.fn.error() is deprecated
在jQuery中,error也是和click一样的事件。注册该事件的处理函数,以前是$(selector).error(function(){}),现在已经被废弃,可以使用$(selector).on('error', function(){})来替代。
示例代码
--------------------------------------------------------------------------------
本文既然自称为“XX大全”,那就应该尽量的全面一些。为了搞明白这些坑是怎么踩进去的,我们最后来写一段js代码,要求是用最少的代码,把jQuery Migration库中所有的坑都踩一遍……也就是让jQuery Migration库打印出来它能打印的所有代码。最终的代码如下所示(博客园竟然没有办法上传附件,只能贴代码了),非常简单易懂。打开index.html文件,然后再按F12键打开控制台,你就可以看到壮观宏伟的控制台警告了^_^
<!-- filename : index.html --><!--<!DOCTYPE html>--> //keng0 怪异模式
<html>
<head>
<meta charset="utf-8" />
<title>jQuery升级踩坑大全</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js" ></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-migrate-1.2.1.js" ></script>
</head>
<body>
<div class="test" id="a">a</div>
<input type="radio" id="b" value="b" />
<input type="radio" id="c" value="c" />
<div id="d" value="d">test</div>
<script type="text/javascript">
//开始踩坑
//使用被废弃分$.attrFn方法
var keng1 = $.attrFn || {};
//该函数在jQuery内部调用,真实项目中从未见过,可忽略,这里只是为了触发一下错误警告
var keng2 = $.attr($("#a"), "class", "xxx", true);
//IE6、7、8中不支持改变输入框的类型
var keng3 = $("input#b").attr("type", "text");
//在该使用prop的地方使用了attr
var keng4 = $("input#c").attr("checked", true);
//使用attr获取property的值,正确的是应该使用 .val()
var keng5 = $("div#d").attr("value");
//使用attr设置property的值,正确的是应该使用 .val('somevalue')
var keng6 = $("div#d").attr("value", "abcd");
//html字符串必须以'<'开头(下面这个是以空格开头)
var keng7 = $(" <div></div>");
//最后一个tag后面还有多余字符串
var keng8 = $("<div></div>abc");
//html字符串不可以以井号‘#'开头
try{
var keng9 = $("#<div></div>");
}catch(e){
console.error(e);
}
//$.parseJSON的参数必须是合法的JSON字符串
var keng10 = $.parseJSON(undefined);
//使用被废弃的$.browser
var keng11 = $.browser;
//使用被废弃的$.sub
var keng12 = $.sub();
$("#c").on("click", function(){});
var keng13 = $("#c").data("events");
//调用了已经不再使用的函数andSelf,该函数已经被addBack替代
var keng14 = $("#c").nextAll().andSelf();
//使用被废弃的$.clean方法
try{
var keng15 = $.clean();
}catch(e){
console.error(e);
}
//"hover"字符串注册事件已经被拆成"mouseenter"和"mouseleave"两个
var keng16 = $("#d").on("hover", function(){/*some code*/});
//jQuery.event.handle并没有收录到官方的API中,新版本已经被移除
var keng17 = function(){
$.event.handle.apply(this, arguments);
};
//全局AJAX事件处理必须绑定到document对象上
var keng18 = $("#c").ajaxStart(function(){});
//使用了被废弃的error方法
var keng19 = $("#c").error(function(){});
//使用了被废弃的toggle方法
var keng20 = $("#d").toggle(function(){/*some code*/}, function(){/*some code*/});
//使用了被废弃的live方法,应该使用on方法替代之
var keng21 = $("#a").live("click", function(){/*some code*/});
//使用了被废弃的die方法,应该使用off方法替代之
var keng22 = $("#a").die("click");
//使用了全局事件函数,目前全局事件只支持AJAX那几个,其他全局事件都不支持
var keng23 = $.event.trigger("click"); 
</script>
</body>
</html>

类别: 无分类 |  评论(0) |  浏览(88) |  收藏
2017年10月08日 15:55:39

万能人

如果您刚生了娃,原单位回不去了,又想给孩子买保险,请和我联系。
如果您的娃9月份开学,自己又不想朝九晚五的上班,请和我联系。
如果您觉得现在的工作很累,又不自由,想换个生活方式,请和我联系。
如果您希望有更多学习机会,给别人更多的帮助,实现人生价值,请和我联系。
如果您喜欢快乐温暖,积极向上的工作环境,爱好旅游,请和我联系,联系电话:110

类别: 无分类 |  评论(0) |  浏览(89) |  收藏
« 1 2345» Pages: ( 1/17 total )