2015年9月30日星期三

uC/OS-II 函数之内存管理相关函数 - One-peace

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
uC/OS-II 函数之内存管理相关函数 - One-peace  阅读原文»

>上文主要介绍了邮箱管理相关的函数,本文介绍内存管理相关的函数:OSMemCreate()内存块创建函数,OSMemGet()函数,OSMemPut()函数,OSMemQuery()函数.以前用过的uC/OS-II笔记分享到这里。

2015年9月29日星期二

哪种监控工具才是运维人的最爱?

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
哪种监控工具才是运维人的最爱?  阅读原文»

哪种监控工具才是运维人的最爱?

哪种监控工具才是运维人的最爱?

那些指标需要监控?我能监控到什么?能监控到何种程度?或许这些问题连你自己都难说清楚。先看看运维兄弟们的现状。

1.运维现状

传统企业的计算机运维是在用户使用计算机过程中发现故障之后,通知运维人员,再由运维人员采取相应的补救措施。运维人员日常大部分时间和精力都花在处理简单且重复的问题上,而且由于故障预警机制不完善,往往是故障发生后才会进行处理,这种情况使运维人员的工作经常处于被动"救火"状态,这种被动的运维模式让IT部门疲惫不堪。运维质量如何提高?生部门能对运维部有满意的评价吗?

目前我们在运维管理过程中缺少明确的角色定义和责任划分,以及自动化的集成运维管理平台,以至于问题出现后很难快速、准确地找到原因,而且在处理故障之后也缺乏必要的跟踪记录。

2.隐藏在流量背后的秘密

网络接口的通端,流量的大小,已满足不了目前运维故障排除的需要。我们需要将流量分析的更深入,更细致。

wKioL1YIrpPwkwLiAAMo8Y4RtNA113.jpg

1 传统流量监控工具看表象

很多漏洞利用攻击、ShellCode攻击都混杂着正常流量进入企业网层层防护关卡。要想知道每个数据包中携带了什么内容,普通的摄像头已经失效,需要更强大的X透视相机-进行协议分析,只有准确理解事物的本质,才能对症下药,Shellcode攻击(下图是shellcode和botnet的实例)和各种蠕虫也是如此。wKioL1YJRA-xRWn9AAkbObm-8fM219.jpg

wKiom1YJRAaDmKDbAAPivWNvabM847.jpg

3.大数据时代下安全运维的新挑战

运维工程师们在大数据时代,下面对大量网络安全事件,若没有有效工具是无法完成分析工作,他们往往面对如下挑战:

1) 每天出现巨大数量的安全报警,管理员很难对这些报警做出响应。

2) 误报严重,管理员无法准确判断故障。

3) 大量重复、零散而没有规律的报警,黑客的一次攻击行动,会在不同阶段触发不同安全设备的告警,这样导致报警数据之间在时间和空间上存在大量重复数据,如果不实现安全事件的关联处理,就无法有效的提高告警质量。

出现这些问题的部分原因是企业缺乏事件监控和诊断等运维工具,因为如果没有高效的管理工具支持,就很难让故障事件得到主动、快速处理。市面上有很多运维监控工具,例如商业版的Cisco Works 2000SolarwindsManageEngine以及专注故障监控的WhatsUp,在开源领域有MRTGNagiosCactiZabbix、Zenoss、OpenNMSGanglia等。由于它们彼此之间没有联系,即便是你部署了这些工具,很多运维人员并没有从中真正解脱出来,原因在于目前的技术虽然能够获取计算机设备、服务器、网络流量,甚至数据库的警告信息,但成千上万条警告信息堆积在一起,让人根本没办法判断问题的根源在哪里,缺乏对信息进行筛选、数据挖掘的能力,其实我们并不缺少工具,商业的也好,开源的也吧,一抓一大把,为什么还是用不好?真正缺少的是分析数据的智能化。

另外我们的查看各种监控系统需要多次登录,查看繁多的界面,更新管理绝大多数工作都是手工操作,即使一个简单的系统变更或更新,往往需要运维人员逐一登录系统,当设备数量达到成百上千时,其工作量之大可想而知。而这样的变更和检查操作在IT 运维中往往每天都在进行,这无疑会占用大量的运维资源。因此,运维工作人员需要统一的集成安全管理平台已迫在眉睫。

过去仅靠几个"技术大拿"来包打天下已不能满足要求,企业需要一种安全的运维平台,满足专业化、标准化和流程化的需要来实现运维工作的自动化管理。因为通过集成监控系统能及时发现故障隐患,主动的告诉用户需要关注的资源,感知网络威胁,把故障消除在萌芽状态。这极大降低了运维人员的工作负担,最大限度地减少维修时间,提高服务质量。

4.人工整合开源工具

既然找不到合适的,我们就把常用的开源工具集成到一个Linux平台,这不是就实现统一管理平台了吗?

wKioL1YIrt6z66R1AAMoiyXE1B0723.jpg

人工整合开源监控系统的难点:

1. 软件和依赖依赖问题难以解决。

2. 各子系统界面重复验证和界面风格问题。

3. 各子系统数据无法共享。

4. 无法实现数据之间关联分析。

5. 无法生成统一格式的报表。

6. 缺乏统一的仪表板来展示重要监控信息。

7. 无法对网络风险进行检测。

8. 各子系统维护难度,增大了运维成本。

实践中发现,这种方案首先遇到了性能问题,一些脚本周期性消耗了较多的CPUI/O资源,所以无法做到实时数据分析。试想有多少且能投入大量人力、时间去开发一个未知的监控平台?

5集成安全运维平台的选择

一个好的安全运维平台需要将事件与IT 流程相关联,一旦监控系统发现性能超标或出现宕机现象,就会触发相关事件以及事先定义好的流程,自动启动故障响应和恢复机制。还需要能够筛选出运维人员完成日常的重复性工作,提高运维效率。要实现这些功能都是常规监控软件CactiZabbix所无法实现。

同时,还要求能够预测网络蠕虫威胁,在故障发生前能够报警,让运维人员把故障消除在萌芽状态,将所产生损失减到最低。总的来说运维人需要能够在一个平台中实现资产管理、分布式部署、漏洞扫描、风险评估、策略管理、实时流量监控、异常流量分析、攻击检测报警、关联分析、风险计算、安全事件告警、事件聚合、日志收集与分析、知识库、时间线分析、统一报表输出、多用户权限管理的功能,这种集成开源工具到底有没有?它去哪儿啦?

目前市面上有两种产品可满足这样的要求,目?p>阅读更多内容

2015年9月28日星期一

基于svg中的path画40%表示的环型图(js类库Raphal) - jinhuazhe2013

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
基于svg中的path画40%表示的环型图(js类库Raphal) - jinhuazhe2013  阅读原文»

【摘要】一、可供参考的文档资料。raphaeljs官网:http://raphaeljs.com/w3c关于path的介绍:http://www.w3.org/TR/2003/REC-SVG11-20030114/paths.htmlmdn关于path的介绍(英文版):https://developer.m... 阅读全文

在表单(input)中id和name的区别 - Y_Y灬vam1288  阅读原文»

在表单(input)中id和name的区别

但是name在以下用途是不能替代的:
1. 表单(form)的控件名,提交的数据都用控件的name而不是id来控制。因为有许多name会同时对应多个控件,比如checkbox和radio,而id必须是全文档中唯一的。此外浏览器会根据name来设定发送到服务器的request。因此如果用id,服务器是无法得到数据的。
2. frame和window的名字,用于在其他frame或window指定target。

例如:<framesetcols="200,*">

<framesrc="/example/html/toc.html">

<framesrc="/example/html/pref.html" name="view_frame">

   </frameset>

等同于其他标签中target="view_window"

<ul>

<li><a href="/example/html/pref.html" target="view_window">Preface</a></li>

<li><a href="/example/html/chap1.html" target="view_window">Chapter1</a></li>

</ul>

以下两者可以通用,但是强烈建议用id不要用name:
1. 锚点,通常以前写作<a name="myname">但name属性只能针对a标签定位,现在可以用任何的元素id来指定:<div id="myid">。

例1:<a href="001">跳到001</a>

    ……

   <aid="001"> (为了兼容,a标签不能空)</a>

Href的值要跟id一致,前面必须加#

例2:想显示某页面的某锚点内容

    <ahref="123.html#001">跳到001</a>

      ……

    <aid="001"> </a>


以下只能用id:
1. label与form控件的关联,
<label for="MyInput">MyInput</label>
<input id="MyInput"type="text">
for属性指定与label关联的元素的id,不可用name替代。
2. CSS的元素选择机制,以#MyId的方式指定应用样式的元素,不能用name替代。


3. 脚本中获得对象:

3.1 如果用DOM的话,则用document.getElementById("MyInput").value,

document.getElementByTagName("MyInput").value

JQ中——$(".firstname").value

3.2提交表单——如果要用name的话,通常先得到包含控件的form,例如document.forms["MyForm"],然后从form再引用name,注意这样得到的是经过计算后将发送给服务器的值。

例子:<head>

    <scripttype="text/javascript">

      functionformSubmit() {

      document.forms["myForm"].submit();

      }

    </script>

  </head>

  <body>

    <form name="myForm"action="http://www.jb51.net/example/html/form_action.asp"method="get">

      Firstname: <input type="text" name="fname" /><br />

      Last name: <input type="text"name="lname" /><br />

      <inputtype="button" onclick="formSubmit()" value="Send formdata!" />

    </form>

  </body>

name与id的还有区别是:
id要符合标识的要求,比如大小写敏感,最好不要包含下划线(因为不兼容CSS)。而name基本上没有什么要求,甚至可以用数字。
补充:name主要是表单元素里才有的属性。通过js的document.表单名称.文本框.value来获取文本框的值,其中的表单名称和文本框名称指的是name,而非表单元素例如div,span等是没有name属性的,而id属性是任何一个HTML元素都会有的。当你需要用js获取非表单元素对象是就得用document.getElementById("id")


本文链接:在表单(input)中id和name的区别,转载请注明。

阅读更多内容

2015年9月26日星期六

DOM选择器API - 小火柴的蓝色理想

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
DOM选择器API - 小火柴的蓝色理想  阅读原文»

getElementById()

  getElementById()方法接收一个参数:要取得元素的ID,若找到相应元素则返回该元素,若不存在则返回null

  【IE7-浏览器bug1】ID属性不区分大小写

<div class="box" id="box"></div>
<script>
var oBox = document.getElementById('Box');
console.log(oBox);
//IE7-可以找到该元素,但其他浏览器都返回null
</script>

   如果页面中多个元素的ID属性相同,则只返回文档中第一次出现的元素

<div class="box" id="box">1</div>
<div class="box" id="box">2</div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.innerHTML);
//1
</script>

  【IE7-浏览器bug2】表单元素的name属性也会被当作ID属性识别出来。因此为了避免这种问题,最好不让表单元素的name属性和其他元素的ID属性相同

<button name="box">0</button>
<div class="box" id="box">1</div>
<div class="box" id="box">2</div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.innerHTML);
//0
</script>

getElementsByTagName() 

  getElementsByTagName()该方法接收一个参数,即要取得元素的标签名,而返回的是包含0或多个元素的NodeList。在HTML文档中,这个方法会返回一个HTMLCollection对象,作为一个动态集合,该对象与NodeList非常类似。对于HTMLCollection对象而言,我们可以向方括号中传入数值或字符串形式的索引值。在后台,会对数值索引调用item()方法,对字符串索引调用namedItem()方法。HTMLCollection对象还有一个方法是namedItem(),可以通过元素的name特性或者直接用方括号来取得集合中的项。但safari和IE都不支持该方法。

<ul class="list" id="list">
<li class="in">1</li>
<li class="in">2</li>
<li class="in" name="in3">3</li>
</ul>
<script>
var oList = document.getElementById('list');
var aIn = oList.getElementsByTagName('li');
console.log(aIn.length);
//3
console.log(aIn[0].innerHTML);//1
console.log(aIn.item(0).innerHTML);//1
console.log(aIn["in3"].innerHTML);//在safari和IE下报错,在其他浏览器下输出3
console.log(aIn.namedItem("in3").innerHTML);//在safari和IE下报错,在其他浏览器下输出3

  要想取得所有的元素,可以向getElementsByTagName传入"*",表示全部

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var aAll = document.getElementsByTagName('*');
//标准浏览器下结果为[html, head, meta, title, body, script]
//
IE8-浏览器下结果为7个,由于它把<!DOCTYPE html>识别为注释,且把注释识别为元素,所以多1个
console.log(aAll);
</script>
</body>
</html>

  在HTML中getElementsByTagName()里的元素不需要区分大小写,但在XML包括XHTML页面需要区分大小写

<div class="box" id="box">1</div>
<script>
var aAll = document.getElementsByTagName('DIV')[0];
console.log(aAll.innerHTML);
//所有浏览器都返回1
</script>

getElementsByName()

  getElementsByName()该方法会返回带有给定name特性的所有元素,所有浏览器都支持。

  最常用的是取得单选按钮。

<ul class="list">
<li class="in">
<input type="radio" value ="red" name ="color" id="colorRed">
<label for="colorRed">红色</label>
</li>
<li class="in">
<input type="radio" value ="blue" name ="color" id="colorBlue">
<label for="colorBlue">蓝色</label>
</li>
<li class="in">
<input type="radio" value ="green" name ="color" id="colorGreen">
<label for="colorGreen">绿色</label>
</li>
</ul>
<script>
var radios = document.getElementsByName('color');
console.log(radios.length)
//3
</script>

getElementsByClassName()

  getElementsByClassName()方法接收一个参数,即一个包含一个或多个类名的字符串,返回带有指定类的所有元素的NodeList。传入多个类名时,类名的先后顺序不重要。(IE8-浏览器不支持)

<ul class="list" style="height:100px">
<li class="in" >1</li>
<li class="in ab" >2</li>
<li class="in ab c">3</li>
</ul>
<script>
var oTest = document.getElementsByClassName('in ab');
console.log(oTest.length);
//2
</script>

classList

  在操作类名时,需要通过className属性添加、删除和替换类名。因为className是一个字符串,所以即使只修改字符串一部分,也必须每次都设置整个字符串的值。要从className字符串中删除一个类名,需要把类名拆开,删除不想要的那个,再重新拼成一个新字符串。(IE9-浏览器不支持)

<ul class="list" style="height:100px">
<li class="in" >1</li>
<li class="in ab" >2</li>
<li class="in ab c">3</li>
</ul>
<script>
var oTest = document.getElementsByClassName('in ab')[1];
function removeClass(obj,str){
var classNames = obj.className.split(/\s+/);
var pos = -1;
for(var i = 0, len = classNames.length; i < len; i++){
if(classNames == str){
pos
= i;
break;
}
};
classNames.splice(i,
1);
obj.className
= classNames.join(' ');
}
removeClass(oTest,
'in');
console.log(oTest.className)
//ab c
</script>

  HTML5为所有元素添加了classList属性,这个classList属性是新集合类型DOMTokenList的实例,它有一个表示自己包含多少元素的length属性,而要取得每个元素可以使用item()方法,也可以使用方括号法。此外,这个新类型还定义如下方法:
  add(value):将给定的字符串值添加到列表中,如果值已存在,则不添加
  contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false
  remove(value):从列表中删除给定的字符串
  toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。

<ul class="list" style="height:100px">
<li class="in" >1</li>
<li class="in ab" >2</li>
<li class="in ab c">3</li>
</ul>
<script>
var oTest = document.getElementsByTagName('li')[1];
console.log(oTest.classList);
//JavaScript中关于隐式转换的一些总结 - andygo  阅读原文»

JavaScript运算符中的隐式转换规律:
一、递增递减运算符(前置、后置)
1.如果包含的是有效数字字符串或者是有效浮点数字符串,则会将字符串转换(Number())为数值,再进行加减操作,返回值的类型是:number类型。
2.如果不包含有效数字字符串,则会将字符串的值转换为NaN,返回值的类型是:number类型。
3.如果是boolean类型,则先会把true或者false转换为1或者0,再进行加减操作,返回值的类型是:number类型。
4.如果是null类型,则先会把null转换为0,在进行加减操作,返回值的类型是:number类型。
5.如果是undefined,则先会把undefined转换为NaN,再进行加减操作,返回值的类型是:number类型。
6.如果是对象,则先会通过对象的valueOf()方法,进行转换,如果返回的是NaN,调用toString()方法,在进行前面的操作,返回值的类型是:number类型。(注:空数组[]会返回0,在进行加减操作,空对象则会返回NaN)。

二、逻辑操作符中的隐式转换规律(注:只有undefined、null、NaN、0、空字符串会被转换为false,其余都为true):
逻辑操作符一般用于语句判断中。通过判断结果返回的值进行后面的语句操作。
1.逻辑非(!)操作符:首先会通过Boolean()函数将其操作值转换为布尔值,然后求反。
2.逻辑与(&&)操作符:如果第一个值经过Boolean()函数转换后为true,则返回第二个操作值,否则返回第一个操作值。如果有一个操作值为null这返回null,如果有一个操作值为undefined,则返回undefined,如果有一个值为NaN,则返回NaN。
3.逻辑或(||)操作符:如果第一个值经过Boolean()函数转换为false,则返回第二个操作值,否则返回第一个操作值。
(注:逻辑操作符的运算为短路逻辑运算:前一个条件已经能够得出结果后续条件不再执行!)

三、关系操作符的隐式转换规律(关系操作符的操作值也可以是任意类型):
1.如果两个操作值都是数值,则直接比较大小。
2.如果两个操作值都是字符串,则字符串进行其Unicode编码进行比较。
3.如果一个操作值是数值,则另一个值转换为数值进行比较。
4.如果一个操作值是对象,则调用对象的valueOf()和toString()方法,然后再进行上述比较。
5.如果一个操作值是布尔值,则将布尔值转换为数值再进行比较。
(注:NaN和任何值都不相等,包括自己,同时它与任何类型比较都会返回false。)

相等操作符==和===的隐式转换规律:
1.布尔值、字符串和数值进行比较,会先将其转换为数值再进行比较。
2.null和undefined比较是相等的,但不是全等的。
3.NaN与任何值都不相等,都会返回false。


本文链接:JavaScript中关于隐式转换的一些总结,转载请注明。

阅读更多内容

2015年9月24日星期四

Web端导出CSV - 木的树

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Web端导出CSV - 木的树  阅读原文»

  前端导出文件大部分还是通过服务器端的方式生成文件,然后传递到客户端。但很多情况下当我们导出CSV时并不需要后端参与,甚至没有后端。

  

  做过WebGIS的同学经常会碰到这种场景,用户的兴趣点数据以csv文件形式上传到web应用中以表格形式展示,并可以编辑属性信息,编辑完成后需要将数据下载到本地。特别是对一些敏感数据,用户不希望传递到应用服务器端,整个过程完全在客户端进行。

  上传过程我们暂且不讨论,只讨论生成CSV以及下载过程。

  

CSV的生成

  问题一:如何分行分列?

  思路:分行使用“\n”,分列使用","

var str = "col1,col2,col3\nvalue1,value2,value3";

  实际应用中发现导出的csv用excel打开后,列可以分开但行无法分开。

  解决方法是,将生成的csv字符串使用encodeURIComponent编码

str = encodeURIComponent(str);

  问题二:字段值中含有特殊符号影响csv文件的正确解读,如:“,”,"\n"

  思路:将含有特殊符号的字段用双引号包装起来,如:a,b => "a,b"

var textField = '"';
if (value && /[,\r\n]/g.test(value)) {
value
= textField + value + textField;
}

  实际应用发现少考虑了一种情况,如果字段值中含有‘ " ’这个符号,经过上方代码处理反而会出现问题:a"b => "a"b"。显然是语法错误。

  解决方法是将"换成"",a"b => "a""b"

var textField = '"';
if (value && /[",\r\n]/g.test(value)) {
value = textField + value.replace(/(")/g, '""') + textField;
}

  在解决以上问题后生成CSV字符串代码如下

//data: 数据数组,每个元素都包含_outFields中指定的字段名
//
_outFields: 字段名称数组
exports.createCSVStr = function(data, _outFields) {
var textField = '"';
var content = "";
var len = 0,
n
= 0,
comma
= "",
value
= "";
try {
array.forEach(_outFields,
function(_field) {
content
= content + comma + _field;
comma
= ",";
});

content
= content + "\r\n";
len
= data.length;
n
= _outFields.length;
for (var i = 0; i < len; i++) {
comma
= "";
for (var m = 0; m < n; m++) {
var _field = _outFields[m];
value
= data[_field];
if (!value && typeof value !== "number") {
value
= "";
}
if (value && /[",\r\n]/g.test(value)) {
value
= textField + value.replace(/(")/g, '""') + textField;
}
content
= content + comma + value;
comma
= ",";
}
content
= content + "\r\n";
}
}
catch (err) {
console.error(err);
content
= "";
}

return content;
};

  问题三:如果字段中含有希伯来文、法语、德语等文字('éà; ça; 12\nà@€; çï; 13'),导出的csv文件在Excel中打开后,这些文字呈现出乱码

  解决方法:严格来说这并不是csv文件的问题,而是Excel处理文件编码方式问题,Excel默认并不是以UTF-8来打开文件,所以在csv开头加入BOM,告诉Excel文件使用utf-8的编码方式。

var BOM = "\uFEFF";
var csvStr = BOM + csvStr;

  实际应用中发现,这种处理方式在windows中的Excel中打开后可以正常显示,但在mac上的Excel无法正确显示。目前没有完全的解决方案,但mac中可以使用自带的Numbers软件打开,不会出现乱码问题。

  

CSV的下载方式

  问题一:如何在解决不同浏览器中的下载问题?

  思路:

  • IE10以下,利用execCommand方法来保存csv文件
    var oWin = window.top.open("about:blank", "_blank");
    oWin.document.write(encodeURIComponent(text));
    oWin.document.close();
    oWin.document.execCommand(
    'SaveAs', true, filename);
    oWin.close();

    在实际应用中浏览器会打开一个新窗口,并弹出保存文件对话框,而对话框中保存类型时,只有html和text两项可选,此时需要在文件名中手动加上“.csv”后缀

  • IE10以及Edge浏览器使用navigator.msSaveBlob(blob);虽然这些浏览器也支持上面的方法,但可以避免上面遇到的问题。
    var BOM = "\uFEFF";
    var csvData = new Blob(, { type: 'text/csv' });
    navigator.msSaveBlob(csvData, filename);

    msSaveBlob是IE的私有方法,只有IE10及以上和Edge浏览器支持。

  • Firefox、Chrome、Safari浏览器中使用a标签,利用html5中增加的download属性来下载csv
    var link = html.create("a", {
    href: 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text)
    ,
    target:
    '_blank',
    download: filename
    },
    this.domNode);
    if (has('safari')) {
    // # First create an event
    var click_ev = document.createEvent("MouseEvents");
    // # initialize the event
    click_ev.initEvent("click", true /* bubble */ , true /* cancelable */ );
    // # trigger the evevnt/
    link.dispatchEvent(click_ev);
    }
    elseDOM特性节点ATTRIBUTE - 小火柴的蓝色理想  阅读原文»

    定义

      每个元素都有一个或多个特性,这些特性的用途是给出相应元素或内容的附加信息。实质上,特性节点就是存在于元素的attributes属性中的节点。

    特征  

      nodeType:2
      nodeName:特性的名称
      nodeValue:特性的值
      parentNode:null
      childNode:chrome、firefox下为undefined,safari下为Text,IE9+下为子元素的特性名,IE8-下报错
        [注意]尽管Attribute也是节点,但却不被认为是DOM文档树的一部分,开发人员常用getAttribute()、setAttribute()、removeAttribute(),很少直接引用特性节点

    <div id="box"></div>
    <script>
    var oBox = document.getElementById('box');
    var oAttr = oBox.attributes;
    //(chrome\safari\IE9+\firefox) 2 id box null
    //
    (IE7-) 2 onmsanimationiteration null null
    console.log(oAttr[0].nodeType,oAttr[0].nodeName,oAttr[0].value,oAttr[0].parentNode)
    //(chrome\firefox) undefined
    //
    (safari) Text
    //
    (IE9+) box
    //
    (IE8-) 报错
    console.log(oAttr[0].childNodes[0])
    </script>

    特性节点属性

      Attr对象有3个属性:name、value和specified
        【1】name是特性名称(与nodeName的值相同)
        【2】value是特性的值(与nodeValue的值相同)
        【3】specified是一个布尔值,用以区别特性是在代码中指定的,还是默认的。这个属性的值如果为true,则意味着要么是在HTML中指定了相应特性,要么是通过setAttribute()方法设置了该属性。在IE中,所有未设置过的特性的该属性值都为false,而在其他浏览器中根本不会为这类特性生成对应的特性节点

    <div class="box" id="box"></div>
    <script>
    var oBox = document.getElementById('box');
    var oAttr = oBox.attributes;
    //(chrome\safari\IE8+)class class true
    //
    (firefox)id id true
    //
    (IE7-)onmsanimationiteration onmsanimationiteration true
    console.log(oAttr[0].name,oAttr[0].nodeName,oAttr[0].name == oAttr[0].nodeName)
    //IE7- "null" null false
    //
    其他浏览器 box box true
    console.log(oAttr[0].value,oAttr[0].nodeValue,oAttr[0].value == oAttr[0].nodeValue)
    //IE7- false
    //
    其他浏览器 true
    console.log(oAttr[0].specified)//true
    </script>
    <div class="box" id="box" name="abc" index="123" title="test"></div>
    <script>
    var oBox = document.getElementById('box');
    console.log(oBox.attributes.id.specified)
    //true
    console.log(oBox.attributes.onclick.specified)//在IE7-浏览器下会返回false,在其他浏览器下会报错
    </script>

    特性属性attributes

      Element类型是使用attributes属性的唯一一个DOM节点类型。attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个动态的集合。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中。

      【attributes属性的四个方法】

        [a]getNamedItem(name):返回nodeName属性等于name的节点
        removeNamedItem(name):从列表中移除nodeName属性等于name的节点
        [c]setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引
        [d]item(pos):返回位于数字pos位置处的节点,也可以用方括号法[]简写

    <div class="box" id="box" name="abc" index="123" title="test"></div>
    <script>
    var oBox = document.getElementById('box');
    console.log(oBox.attributes);
    //NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
    var getTest = oBox.attributes.getNamedItem("index");
    console.log(getTest);
    //index = "123"
    var removeTest = oBox.attributes.removeNamedItem("class");
    console.log(removeTest);
    //class = "box"
    console.log(oBox.attributes.getNamedItem("class"));//null
    console.log(oBox.attributes.setNamedItem(removeTest));//null
    console.log(oBox.attributes.setNamedItem(getTest));//index = "123"
    console.log(oBox.attributes.item(0));//id="box"(每个浏览器获取的不一样)
    </script>

      attributes属性中包含一系列节点,每个节点的nodeName就是特性的名称,节点的nodeValue就是特性的值

    <div class="box" id="box" name="abc" index="123" title="test"></div>
    <script>
    var oBox = document.getElementById('box');
    console.log(oBox.attributes);
    //NamedNodeMap {0: class, 1: id, 2: name, 3: index, 4: title}
    console.log(oBox.attributes.id.nodeName);//"id"
    console.log(oBox.attributes.id.nodeValue);//"box"
    </script>

      【特性遍历】

        attributes属性主要用于特性遍历。在需要将DOM结构序列化为XML或HTML字符串时,多数都会涉及遍历元素特性

    function outputAttributes(element){
    var pairs = new Array(),attrName,attrValue,i,len;
    for(i = 0,len=element.attributes.length;i<len;i++){
    attrName
    = element.attributes.nodeName;
    attrValue
    = element.attributes.nodeValue;
    pairs.push(attrName
    +"=\"" + attrValue + "\"");
    }
    return pairs.join(" ");
    }

        

        [注意1]针对attributes对象中的特性,不同浏览器返回的顺序不同

    <div class="box" id="box" name="abc" index="123" title="test"></div>
    <script>
    function outputAttributes(element){
    var pairs = new Array(),attrName,attrValue,i,len;
    for(i = 0,len=element.attributes.length;i<len;i++){
    attrName
    = element.attributes.nodeName;
    attrValue
    = element.attributes.nodeValue;
    pairs.push(attrName
    +"=\"" + attrValue + "\"");
    }
    return pairs.join(" ");
    }
    //(chrome\safari)class="box" id="box" name="abc" index="123" title="test"
    //
    (firefox)title="test" index="123" name="abc" id="box" class="box"
    //
    (IE8+)title="test" class="box" id="box" index="123" name="abc"阅读更多内容

2015年9月23日星期三

Linux 高可用(HA)集群之keepalived

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Linux 高可用(HA)集群之keepalived  阅读原文»

用户名:飞残月 文章数:125 评论数:18
访问量:6882:2273:1284:5 注册日期:2015-02-25

Linux 高可用(HA)集群之keepalived

一、keepalived介绍

1、Keepalived 定义

Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候, 备份服务器就会接管虚拟IP,继续提供服务,从而保证了高可用性。Keepalived是VRRP的完美实现,因此在介绍keepalived之前,先介绍一下VRRP的原理。

2、VRRP 协议简介

在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接。对于这样的情况,它们之间路由怎样选择?主机如何选定到达目的主机的下一跳路由,这个问题通常的解决方法有二种:

  • 在主机上使用动态路由协议(RIP、OSPF等)

  • 在主机上配置静态路由

很明显,在主机上配置动态路由是非常不切实际的,因为管理、维护成本以及是否支持等诸多问题。配置静态路由就变得十分流行,但路由器(或者说默认网关default gateway)却经常成为单点故障。VRRP的目的就是为了解决静态路由单点故障问题,VRRP通过一竞选(election)协议来动态的将路由任务交给LAN中虚拟路由器中的某台VRRP路由器。

3、VRRP 工作机制

在一个VRRP虚拟路由器中,有多台物理的VRRP路由器,但是这多台的物理的机器并不能同时工作,而是由一台称为MASTER的负责路由工作,其它的都是BACKUP,MASTER并非一成不变,VRRP让每个VRRP路由器参与竞选,最终获胜的就是MASTER。MASTER拥有一些特权,比如,拥有虚拟路由器的IP地址,我们的主机就是用这个IP地址作为静态路由的。拥有特权的MASTER要负责转发发送给网关地址的包和响应ARP请求。

VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包(多播地址224.0.0.18)形式发送的。虚拟路由器由VRID(范围0-255)和一组IP地址组成,对外表现为一个周知的MAC地址。所以,在一个虚拟路由 器中,不管谁是MASTER,对外都是相同的MAC和IP(称之为VIP)。客户端主机并不需要因为MASTER的改变而修改自己的路由配置,对客户端来说,这种主从的切换是透明的。

在一个虚拟路由器中,只有作为MASTER的VRRP路由器会一直发送VRRP通告信息(VRRPAdvertisement message),BACKUP不会抢占MASTER,除非它的优先级(priority)更高。当MASTER不可用时(BACKUP收不到通告信息), 多台BACKUP中优先级最高的这台会被抢占为MASTER。这种抢占是非常快速的(<1s),以保证服务的连续性。由于安全性考虑,VRRP包使用了加密协议进行加密。

4、VRRP 工作流程

(1).初始化:

路由器启动时,如果路由器的优先级是255(最高优先级,路由器拥有路由器地址),要发送VRRP通告信息,并发送广播ARP信息通告路由器IP地址对应的MAC地址为路由虚拟MAC,设置通告信息定时器准备定时发送VRRP通告信息,转为MASTER状态;否则进入BACKUP状态,设置定时器检查定时检查是否收到MASTER的通告信息。

(2).Master

  • 设置定时通告定时器;

  • 用VRRP虚拟MAC地址响应路由器IP地址的ARP请求;

  • 转发目的MAC是VRRP虚拟MAC的数据包;

  • 如果是虚拟路由器IP的拥有者,将接受目的地址是虚拟路由器IP的数据包,否则丢弃;

  • 当收到shutdown的事件时删除定时通告定时器,发送优先权级为0的通告包,转初始化状态;

  • 如果定时通告定时器超时时,发送VRRP通告信息;

  • 收到VRRP通告信息时,如果优先权为0,发送VRRP通告信息;否则判断数据的优先级是否高于本机,或相等而且实际IP地址大于本地实际IP,设置定时通告定时器,复位主机超时定时器,转BACKUP状态;否则的话,丢弃该通告包;

(3).Backup

  • 设置主机超时定时器;

  • 不能响应针对虚拟路由器IP的ARP请求信息;

  • 丢弃所有目的MAC地址是虚拟路由器MAC地址的数据包;

  • 不接受目的是虚拟路由器IP的所有数据包;

  • 当收到shutdown的事件时删除主机超时定时器,转初始化状态;

  • 主机超时定时器超时的时候,发送VRRP通告信息,广播ARP地址信息,转MASTER状态;

  • 收到VRRP通告信息时,如果优先权为0,表示进入MASTER选举;否则判断数据的优先级是否高于本机,如果高的话承认MASTER有效,复位主机超时定时器;否则的话,丢弃该通告包;

5、ARP查询处理

当内部主机通过ARP查询虚拟路由器IP地址对应的MAC地址时,MASTER路由器回复的MAC地址为虚拟的VRRP的MAC地址,而不是实际网卡的 MAC地址,这样在路由器切换时让内网机器觉察不到;而在路由器重新启动时,不能主动发送本机网卡的实际MAC地址。如果虚拟路由器开启的ARP代理 (proxy_arp)功能,代理的ARP回应也回应VRRP虚拟MAC地址;好了VRRP的简单讲解就到这里,我们下来讲解一下Keepalived的案例。

6、keepalived组成

keepalived主要有三个模块,分别是core、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。

wKioL1X-xN-zECheAAHbtJZea5c950.jpg

二、keepalived的配置文件说明

keepalived只有一个配置文件keepalived.conf,里面主要包括以下几个配置区域,分别是global_defs、static_ipaddress、static_routes、vrrp_script、vrrp_instance和virtual_server。

1、global_defs区域

主要是配置故障发生时的通知对象以及机器标识。

  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_connect_timeout 30     enable_traps     router_id LVS_DEVEL  }  
  • notification_email 故障发生时给谁发邮件通知。

  • notification_email_from 通知邮件从哪个地址发出。

  • smpt_server 通知邮件的smtp地址。

  • smtp_connect_timeout 连接smtp服务器的超时时间。

  • enable_traps 开启SNMP陷阱(Simple Network Management Protocol)。

  • 傻瓜式操作Nagios图解  阅读原文»

    傻瓜式操作Nagios图解

    傻瓜式操作Nagios

    不少接触Nagios的朋友都会觉得安装配置困难,应用在企业网中所花费的时间成本很高,下面通过OSSIM来搞定它把。

    为了节省资源,首先在淘汰的机器上安装一个低版本的OSSIM系统,接下来在WebUI中无需编写任何代码和配置文件便可开启傻瓜化操作Nagios之旅。

    1.在左侧菜单中设置网络发现。

    wKioL1X-FUTRXMWbAAK0bHsPKWg116.jpg

    开始扫描,发现设备,点击完成后可出现扫描结果,接着选则更新数据库。

    2.主机列表

    wKiom1X-E2aj1mCHAALTB6AR5bs411.jpg

    选择一台主机开始设置监控项
    wKioL1X-Fcrxki3RAAH7Y9yB8FM399.jpg

    查看监控效果

    wKioL1X-FfORSqaKAAN9oh4djFQ014.jpg

    3.查看拓扑
    wKiom1X-E9CCBuRFAAR7GOL6HiI463.jpg

    4.列出另一网段更多主机,列出主机状态.
    wKioL1X-FiPB3g-IAAOJlN1VdwQ950.jpg
    很轻松就完成了Nagios设置,今后增减服务器都可以通过这种图形化方式修改Nagios,非常方便,刚才说了这只是一个低版本的OSSIM所具功能,至于新版本还有那些本事,大家可以参考我的OSSIM专栏。

    如果大家也想找台就机器,内存只要大于2GB就可以安装下面提供的32位版本,有兴趣就去试试吧。


    OSSIM 2.3 镜像下载

    本文出自 "李晨光原创技术博客" 博客,请务必保留此出处http://chenguang.blog.51cto.com/350944/1696387

    分享至 一键收藏,随时查看,分享好友!
    每日博报 精彩不止一点
    返回顶部

    阅读更多内容

2015年9月22日星期二

zzuoj10408--最少换乘(***最短路***) - 微风向上

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
zzuoj10408--最少换乘(***最短路***) - 微风向上  阅读原文»

10408: C.最少换乘

Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 38 Solved: 10
[Submit][Status][Web Board]

Description

欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行。Dr. Kong决定利用暑假好好游览一番。。

年轻人旅游不怕辛苦,不怕劳累,只要费用低就行。但Dr. Kong年过半百,他希望乘坐BUS从住的宾馆到想去游览的景点,期间尽可量地少换乘车。

Dr. Kon买了一张旅游地图。他发现,市政部门为了方便游客,在各个旅游景点及宾馆,饭店等地方都设置了一些公交站并开通了一些单程线路。每条单程线路从某个公交站出发,依次途经若干个站,最终到达终点站。

但遗憾的是,从他住的宾馆所在站出发,有的景点可以直达,有的景点不能直达,则他可能要先乘某路BUS坐上几站,再下来换乘同一站的另一路BUS, 这样须经过几次换乘后才能到达要去的景点。

为了方便,假设对该城的所有公交站用12……N编号。Dr. Kong所在位置的编号为1,他将要去的景点编号为N

请你帮助Dr. Kong寻找一个最优乘车方案,从住处到景点,中间换车的次数最少。

Input

第一行: K 表示有多少组测试数据。(2k8

接下来对每组测试数据:

1: M N 表示有M条单程公交线路,共有N站。(1<=M<=100 1<N<=500

2~M+1行:每行描述一路公交线路信息,从左至右按运行顺序依次给出了该线路上的所有站号,相邻两个站号之间用一个空格隔开。

Output

对于每组测试数据,输出一行,如果无法乘坐任何线路从住处到达景点,则输出"N0",否则输出最少换车次数,输出0表示不需换车可以直达。

Sample Input

2
3 7
6 7
4 7 3 6
2 1 3 5
2 6
1 3 5
2 6 4 3

Sample Output

2
NO

HINT

Source

第八届河南省赛

看题目就知道喽, 换路线最少次数。 指定方向1 --> n, 有向边。 为啥用最短路可以解出来, 现在有点儿蒙圈。 明天好好想想。

#include <cstdio>
#include
<cstring>
#include
<iostream>
#define M 501
using namespace std;
const int INF = 0x3f3f3f3f;
int map[M][M], dis[M], vis[M], num[M]; char str[1001];
int n, m;
void init()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j)
map[j]
= 0;
else
map[j]
= INF;
}
}
void GetMap()
{
int cnt;
for(int i = 1; i <= m; i++)
{
cnt
= 0; gets(str);
for(int j = 0; j < strlen(str); j++)
if(str[j] != ' ')
{
int sum = 0;
while(str[j] != ' ' && j < strlen(str))
{
sum
= sum*10 + (str[j] - '0');
++j;
}
num[cnt
++] = sum;
}
for(int j = 0; j < cnt; j++)
for(int k = j + 1; k < cnt; k++)
map[num[j]][num[k]]
= Shell 常用命令总结 - 天才白痴梦  阅读原文»

Shell常用命令总结

1 ls命令:列出文件

ls -la 列出当前目录下的所有文件和文件夹

ls a* 列出当前目录下所有以a字母开头的文件

ls -l *.txt 列出当前目录下所有后缀名为txt的文件

2 cp命令:复制

cp a.txt b.txt : 把文件a的内容复制到b文件

cp a.txt ./test : 把文件a复制到text目录下

cp -a test test2:递归的把目录test下所有文件(包括隐藏的文件)复制到新的目录 test2

3 cat命令:查看 组合文件

cat a.txt:查看文件的内容

cat a.txt >> b.txt:把a文件的内容组合到b文件内容的末尾

cat -n a.txt:查看文件并给文件标上行号

4 touch命令:建立文件

touch a.txt:建立一个名为atxt类型文件

5 rm命令:删除文件

rm -rf a.txt:强制删除文件a.txt

tm -i a.txt:删除文件前会有提示是否确定删除该文件

6 mkdir命令:创建目录

mkdir test:创建一个名为test的目录

7 rmdir命令:删除目录

tmdir test:删除一个目录

8 echocat命令:添加内容

echo “hello world!” >> a.txt:添加内容到文件a里面

cat <<EOF>> a.txt : 可以添加多行语句到文件本身内容的末尾

cat <<EOF> a.txt:添加内容到文件并覆盖到原始的内容

9 mv命令:移动 重命名文件

mv a.txt b.txt:文件a重新命名为b

mv a.txt ./test:把文件移动到一个目录下

10 cd命令:更换目录

cd ~ : 切换到用户目录

cd .. :返回到上一层目录

cd ../.. :返回到上二层目录

11 grep命令:搜索文件

ls -la | grep a.txt :搜索a.txt文件

12 find命令:查找文件和目录

find filename:查找当前目录下是否有该文件/目录

13 rz sz命令:上传和下载文件

14 head命令:显示文件的前10行内容

15 tail命令:显示文件最后10行内容

总结:

之前有段时间学习了下Shell 常用的文件处理命令,上面列举的这些只是Shell命令的非常一小部分,Shell命令有非常强大和快速的处理能力,给我们平常的学习和工作任务提供了很多方便。再则,单就以上的15个命令而言,其功能远不止列举的那一两条命令这么简单,大家可以通过ls --help(其他命令以此类推)来查看命令的用法。


本文链接:Shel

阅读更多内容

2015年9月20日星期日

一步一步搭建客服系统 (6) chrome桌面共享 - 疯吻IT

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
一步一步搭建客服系统 (6) chrome桌面共享 - 疯吻IT  阅读原文»

本文介绍了如何在chrome下用webrtc来实现桌面共。因为必要要用https来访问才行,因此也顺带介绍了如何使用SSL证书。

1 chrome扩展程序

  • 先下载扩展程序示例:

https://github.com/otalk/getScreenMedia/tree/master/chrome-extension-sample

http://yunpan.cn/cHfwnrZcG2hsH 访问密码 1cf9

  • 打开 manifest.json 文件,修改下面的内容:

"content_scripts": [ {
"js": [ "content.js" ],
"matches": [ "
https://localhost:*/*" ]
}],

  • 加载扩展程序

打开chrome,输入 chrome://extensions/ 以打开chrome的扩展程序,按下图的顺序加载:

image

2 共享桌面

共享桌面方法:

webrtc.shareScreen()

停止共享桌面方法:

webrtc.stopScreenShare()

.

3 本机显示共享的内容

本机显示:

个人觉得本机没必要,在点击时放大共享的内容,所以把上面click事件注释掉了。


移除显示:

.

4 接收桌面共享

接收桌面共享: