ASP.NET Core 性能对比评测(ASP.NET,Python,Java,NodeJS)

测试结果的汇总统计:

编号 对比方 系统环境 宿主环境 测试结果(QPS)
1 ASP.NET Core vs ASP.NET Core Windows Kestrel vs IIS 45.6k vs 15.2k
2 ASP.NET Core vs ASP.NET Windows IIS vs IIS 15.2k vs 18.2k
3 ASP.NET Core vs ASP.NET Windows Kestrel vs IIS 45.6k vs 18.2k
4 ASP.NET Core vs Python Django Linux Kestrel vs uwsgi 26.7k vs 1.57k
5 ASP.NET Core vs Java Servlet Linux Kestrel vs Tomcat 26.7k vs 18.3k
6-1 ASP.NET Core vs NodeJS Express Linux Kestrel vs self host 26.7k vs 15.6k
6-2 ASP.NET Core vs NodeJS Koa Linux Kestrel vs self host 26.7k vs 17.5k

作为微软的下一代 ASP.NET 框架,ASP.NET Core没有让我们失望,通过本次测试,我们大概对ASP.NET Core的性能心里有底了。一个圈子的良好发展需要社区的共同参与,也希望大家共同为.NET Core社区贡献自己的力量,同时也希望看到本篇文章的CTOs们以后在平台和框架选择的过程中考虑一下ASP.NET Core,因为她真的很优秀。

 

 

 

原文:https://www.cnblogs.com/savorboard/archive/2016/10/17/dotnet-benchmarks.html

 

 

 

 

 

 

发表在 article | ASP.NET Core 性能对比评测(ASP.NET,Python,Java,NodeJS)已关闭评论

Raft 更易理解的分布式一致性算法

一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前。

拜占庭将军问题

Leslie Lamport 在三十多年前发表的论文《拜占庭将军问题》(参考[1])。

拜占庭位于如今的土耳其的伊斯坦布尔,是东罗马帝国的首都。由于当时拜占庭罗马帝国国土辽阔,为了防御目的,因此每个军队都分隔很远,将军与将军之间只能靠信差传消息。在战争的时候,拜占庭军队内所有将军必需达成 一致的共识,决定是否有赢的机会才去攻打敌人的阵营。但是,在军队内有可能存有叛徒和敌军的间谍,左右将军们的决定又扰乱整体军队的秩序,在进行共识时,结果并不代表大多数人的意见。这时候,在已知有成员不可靠的情况下,其余忠诚的将军在不受叛徒或间谍的影响下如何达成一致的协议,拜占庭问题就此形成。拜占庭假设是对现实世界的模型化,由于硬件错误、网络拥塞或断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为。

Lamport 一直研究这类问题,发表了一系列论文。但综合总结一下就是回答下面三个问题:

  1. 类似拜占庭将军这样的分布式一致性问题是否有解?
  2. 如果有解的话需要满足什么样的条件?
  3. 在特定前提条件的基础上,提出一种解法。

前两个问题 Lamport 在论文《拜占庭将军问题》已经回答,而第三个问题在后来的论文 《The Part-Time Parliament》中提出了一种算法并命名为 Paxos。这篇论文使用了大量的数学证明,而我基本就看不懂了(数学符号都认不全-。-;),考虑到大家理解起来都比较困难,后来 Lamport 又写了另外一篇论文 《Paxos Made Simple》完全放弃了所有数学符号的证明,使用纯英文的逻辑推导。我勉强逐字看了一遍,然后感觉若有所悟,但你问我搞懂了吗,我的标准应该还是没懂。对我来说理解一个算法有个明确的标准,就是真的懂了会在头脑里能将算法映射为代码,而看完后面一篇论文仅仅是若有所悟还达不到能映射为代码的清晰度。

虽然 Lamport 认为 Paxos 很 simple,但也许只是针对他的头脑而言。事实是大家理解起来都还是很困难,所以 Raft 就是建立在希望得到一个更易于理解的 Paxos 算法的替代品。把可理解性作为算法的主要目标之一,从论文题目就可看出来《In Search of an Understandable Consensus Algorithm》。

在进入正题前,我想起一个旧故事可以很直观的感受对一个问题不同的思维视角在可理解性上的差异。

不同视角的可理解性

依稀记得大约在二十年前,我还在读初中时在一本可能大概叫《数学中的发散思维》(不能很清晰记得书名了)的书中看到这么一个有趣的问题。

甲乙两人轮流在一张圆桌上平放黑白围棋子,每次放一子,棋子不许重叠,谁先没有地方放就输。
请问怎样放才能赢?

这个问题有两层意思,第一,有没有一种放法保证必赢?第二,如果有怎么证明?这里先停顿下,思考十秒钟。

上面的图回答了这个问题,就是先行者必胜,这里使用了三种不同的思维方式。

  1. 假如桌子只有一个围棋子那么大。
  2. 假如桌子无限大,先行者先占住圆心,由于圆是对称图形,所以只要对手还能找到位置放,你总能在对称的另一面找到位置放。
  3. 一个圆中可画单数个直径相等且互切的小圆。

三种不同的思维方式在可理解性难度上逐渐加深。第一种是极简化思维,但数学上是不严谨的。第二种是极限思维,和第一种结合起来就是数学归纳法了,在数学上是严谨的。第三种是形象思维,使用了几何学概念,但对于没有几何学基础知识的人就很难理解了。

Raft 协议的易理解性描述

虽然 Raft 的论文比 Paxos 简单版论文还容易读了,但论文依然发散的比较多,相对冗长。读完后掩卷沉思觉得还是整理一下才会更牢靠,变成真正属于自己的。这里我就借助前面黑白棋落子里第一种极简思维来描述和概念验证下 Raft 协议的工作方式。

在一个由 Raft 协议组织的集群中有三类角色:

  1. Leader(领袖)
  2. Follower(群众)
  3. Candidate(候选人)

就像一个民主社会,领袖由民众投票选出。刚开始没有领袖,所有集群中的参与者都是群众,那么首先开启一轮大选,在大选期间所有群众都能参与竞选,这时所有群众的角色就变成了候选人,民主投票选出领袖后就开始了这届领袖的任期,然后选举结束,所有除领袖的候选人又变回群众角色服从领袖领导。这里提到一个概念「任期」,用术语 Term 表达。关于 Raft 协议的核心概念和术语就这么多而且和现实民主制度非常匹配,所以很容易理解。三类角色的变迁图如下,结合后面的选举过程来看很容易理解。

Leader 选举过程

在极简的思维下,一个最小的 Raft 民主集群需要三个参与者(如下图:A、B、C),这样才可能投出多数票。初始状态 ABC 都是 Follower,然后发起选举这时有三种可能情形发生。下图中前二种都能选出 Leader,第三种则表明本轮投票无效(Split Votes),每方都投给了自己,结果没有任何一方获得多数票。之后每个参与方随机休息一阵(Election Timeout)重新发起投票直到一方获得多数票。这里的关键就是随机 timeout,最先从 timeout 中恢复发起投票的一方向还在 timeout 中的另外两方请求投票,这时它们就只能投给对方了,很快达成一致。

选出 Leader 后,Leader 通过定期向所有 Follower 发送心跳信息维持其统治。若 Follower 一段时间未收到 Leader 的心跳则认为 Leader 可能已经挂了再次发起选主过程。

Leader 节点对一致性的影响

Raft 协议强依赖 Leader 节点的可用性来确保集群数据的一致性。数据的流向只能从 Leader 节点向 Follower 节点转移。当 Client 向集群 Leader 节点提交数据后,Leader 节点接收到的数据处于未提交状态(Uncommitted),接着 Leader 节点会并发向所有 Follower 节点复制数据并等待接收响应,确保至少集群中超过半数节点已接收到数据后再向 Client 确认数据已接收。一旦向 Client 发出数据接收 Ack 响应后,表明此时数据状态进入已提交(Committed),Leader 节点再向 Follower 节点发通知告知该数据状态已提交。

在这个过程中,主节点可能在任意阶段挂掉,看下 Raft 协议如何针对不同阶段保障数据一致性的。

1. 数据到达 Leader 节点前

这个阶段 Leader 挂掉不影响一致性,不多说。

2. 数据到达 Leader 节点,但未复制到 Follower 节点

这个阶段 Leader 挂掉,数据属于未提交状态,Client 不会收到 Ack 会认为超时失败可安全发起重试。Follower 节点上没有该数据,重新选主后 Client 重试重新提交可成功。原来的 Leader 节点恢复后作为 Follower 加入集群重新从当前任期的新 Leader 处同步数据,强制保持和 Leader 数据一致。

3. 数据到达 Leader 节点,成功复制到 Follower 所有节点,但还未向 Leader 响应接收

这个阶段 Leader 挂掉,虽然数据在 Follower 节点处于未提交状态(Uncommitted)但保持一致,重新选出 Leader 后可完成数据提交,此时 Client 由于不知到底提交成功没有,可重试提交。针对这种情况 Raft 要求 RPC 请求实现幂等性,也就是要实现内部去重机制。

4. 数据到达 Leader 节点,成功复制到 Follower 部分节点,但还未向 Leader 响应接收

这个阶段 Leader 挂掉,数据在 Follower 节点处于未提交状态(Uncommitted)且不一致,Raft 协议要求投票只能投给拥有最新数据的节点。所以拥有最新数据的节点会被选为 Leader 再强制同步数据到 Follower,数据不会丢失并最终一致。

5. 数据到达 Leader 节点,成功复制到 Follower 所有或多数节点,数据在 Leader 处于已提交状态,但在 Follower 处于未提交状态

这个阶段 Leader 挂掉,重新选出新 Leader 后的处理流程和阶段 3 一样。

6. 数据到达 Leader 节点,成功复制到 Follower 所有或多数节点,数据在所有节点都处于已提交状态,但还未响应 Client

这个阶段 Leader 挂掉,Cluster 内部数据其实已经是一致的,Client 重复重试基于幂等策略对一致性无影响。

7. 网络分区导致的脑裂情况,出现双 Leader

网络分区将原先的 Leader 节点和 Follower 节点分隔开,Follower 收不到 Leader 的心跳将发起选举产生新的 Leader。这时就产生了双 Leader,原先的 Leader 独自在一个区,向它提交数据不可能复制到多数节点所以永远提交不成功。向新的 Leader 提交数据可以提交成功,网络恢复后旧的 Leader 发现集群中有更新任期(Term)的新 Leader 则自动降级为 Follower 并从新 Leader 处同步数据达成集群数据一致。

综上穷举分析了最小集群(3 节点)面临的所有情况,可以看出 Raft 协议都能很好的应对一致性问题,并且很容易理解。

总结

就引用 Raft 论文最后的一节的综述来总结本文吧。

算法以正确性、高效性、简洁性作为主要设计目标。
虽然这些都是很有价值的目标,但这些目标都不会达成直到开发者写出一个可用的实现。
所以我们相信可理解性同样重要。

深以为然,想想 Paxos 算法是 Leslie Lamport 在 1990 年就公开发表在了自己的网站上,想想我们是什么时候才听说的?什么时候才有一个可用的实现?而 Raft 算法是 2013 年发表的,大家在参考[5]上面可以看到有多少个不同语言开源的实现库了,这就是可理解性的重要性。

参考

[1]. LESLIE LAMPORT, ROBERT SHOSTAK, MARSHALL PEASE. The Byzantine General Problem. 1982
[2]. Leslie Lamport. The Part-Time Parliament. 1998
[3]. Leslie Lamport. Paxos Made Simple. 2001
[4]. Diego Ongaro and John Ousterhout. Raft Paper. 2013
[5]. Raft Website. The Raft Consensus Algorithm
[6]. Raft Demo. Raft Animate Demo

 

文章来源:

https://www.cnblogs.com/mindwind/p/5231986.html

 

 

 

发表在 article | 标签为 | Raft 更易理解的分布式一致性算法已关闭评论

分布式事务与一致性算法 paxos & raft & zab

..

1.CAP原理

  • 要想数据高可用,就得写多份数据
  • 写多分数据就会导致数据一致性问题
  • 数据一致性问题会引起性能问题

2.一致性模型

  1. 弱一致性
  2. 最终一致性(一段时间达到一致性)
  3. 强一致
  • 1、2 异步冗余;3是同步冗余

3. 扩展服务的方案

  • 数据分区: uid % 16
  • 数据镜像:让多有的服务器都有相同的数据,提供相当的服务(冗余存储,一般3份为好)

4.两种方案的事务问题

  1. A向B汇钱,两个用户不在一个服务器上
  2. 镜像:在不同的服务器上对同一数据的写操作如何保证一致性。

5. 解决一致性事务问题的技术

1. Master -Slave

  • 读写请求由Master负责
  • 写请求写到Master后,由Master同步到Slave上
    • 由Master push or Slave pull
    • 通常是由Slave 周期性来pull,所以是最终一致性

问题: 若在 pull 周期内(不是期间?),master挂掉,那么会导致这个时间片内的数据丢失

  • 若不想让数据丢掉,Slave 只能成为 ReadOnly方式等Master恢复
  • 若容忍数据丢失,可以让 Slave代替Master工作

如何保证强一致性?

  • Master 写操作,写完成功后,再写 Slave,两者成功后返回成功。若 Slave失败,两种方法
    1. 标记 Slave 不可用报错,并继续服务(等恢复后,再同步Master的数据,多个Slave少了一个而已)
    2. 回滚自己并返回失败

2. Master-Master

  • 数据同步一般是通过 Master 间的异步完成,所以是最终一致
  • 好处: 一台Master挂掉,另外一台照样可以提供读写服务。当数据没有被赋值到别的Master上时,数据会丢失。
  • 对同一数据的处理问题:Dynamo的Vector Clock的设计(记录数据的版本号和修改者),当数据发生冲突时,要开发者自己来处理

3.两阶段提交 Two Phase Commit _ 2PC

  1. 第一阶段:针对准备工作
    • 协调者问所有节点是否可以执行提交
    • 参与者开始事务,执行准备工作:锁定资源(获取锁操作)
    • 参与者响应协调者,如果事务的准备工作成功,则回应"可以提交",否则,拒绝提交
  2. 第二阶段:
    • 若都响应可以提交,则协调者项多有参与者发送正式提交的命令(更新值),参与者完成正式提交,释放资源,回应完成。协调者收到所有节点的完成响应后结束这个全局事务.。若参与者回应拒绝提交,则协调者向所有的参与者发送回滚操作,并释放资源,当收到全部节点的回滚回应后,取消全局事务
  3. 存在的问题:若一个没提交,就会进行回滚
    • 第一阶段:若消息的传递未接收到,则需要协调者作超时处理,要么当做失败,要么重载
    • 第二阶段:若参与者的回应超时,要么重试,要么把那个参与者即为问题节点,提出整个集群
    • 在第二阶段中,参与者未收到协调者的指示(也许协调者挂掉),则所有参与者会进入“不知所措” 的状态(但是已经锁定了资源),所以引入了三段提交

4. 三段提交:把二段提交的第一阶段 break 成了两段

  1. 询问
  2. 锁定资源(获取锁)
  3. 提交
  • 核心理念:在询问的时候并不锁定资源,除非所有人都同意了,才开始锁定
  • 好处:当发生了失败或超时时,三段提交可以继续把状态变为Commit 状态,而二段提交则不知所措?

5. Raxos 算法(少数服从多数)

  • 解决的问题:在一个可能发生异常的分布式系统中如何就某个值达成一致,让整个集群的节点对某个值的变更达成一致
  • 任何一个节点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的节点同意(所以节点数总是单数)—— 版本标记。虽然一致性,但是只能对一个操作进行操作啊??
  • 当一个Server接收到比当前版本号小的提案时,则拒绝。当收到比当前大的版本号的提案时,则锁定资源,进行修改,返回OK. 也就是说收到超过一半的最大版本的提案才算成功。

核心思想

  1. 在抢占式访问权的基础上引入多个acceptor,也就是说当一个版本号更大的提案可以剥夺版本号已经获取的锁。
  2. 后者认同前者的原则:
    • 在肯定旧epoch 无法生成确定性取值时,新的 epoch 会提交自己的valu
    • 一旦 旧epoch形成确定性取值,新的 epoch肯定可以获取到此取值,并且会认同此取值,不会被破坏。

步骤

  1. P1 请求Acceptor的 #1,Acceptor 这时并没有其他线程获取到锁,所以把锁交给 P1,并返回这时 #1 的值为null
  2. 然后 P1 向 第一个 Acceptor 提交 #1 的值,Acceptor 接受并返回 OK
  3. 这个时候,P2向Acceptor请求#1上的锁,因为版本号更大,所以直接抢占了 P1 的锁。这时 Acceptor 返回了 OK并且返回了 #1 的值
  4. 这时 P1 P向 后面两个 Acceptor 提交 #1 的值,但是由于中间的那个Acceptor 版本号已经更改为 2 了,所以拒绝P1。第三个 Acceptor 接受了,并且返回了 OK
  5. 由于后者认同前者的原则,这时 P1 已经形成确定性取值了 V1 了,这时新的 P2 会认同此取值,而不是提交自己的取值。所以,P2会选择最新的那个取值 也就是V1 进行提交。这时Acceptor 返回 OK

6.ZAB 协议 ( Zookeeper Atomic Broadcast) 原子广播协议:保证了发给各副本的消息顺序相同

定义:原子广播协议 ZAB 是一致性协议,Zookeeper 把其作为数据一致性的算法。ZAB 是在 Paxos 算法基础上进行扩展而来的。Zookeeper 使用单一主进程 Leader用于处理客户端所有事务请求,采用 ZAB 协议将服务器状态以事务形式广播到所有 Follower 上,由于事务间可能存在着依赖关系,ZAB协议保证 Leader 广播的变更序列被顺序的处理,一个状态被处理那么它所依赖的状态也已经提前被处理

核心思想:保证任意时刻只有一个节点是Leader,所有更新事务由Leader发起去更新所有副本 Follower,更新时用的是 两段提交协议,只要多数节点 prepare 成功,就通知他们commit。各个follower 要按当初 leader 让他们 prepare 的顺序来 apply 事务

协议状态

  1. Looking:系统刚启动时 或者 Leader 崩溃后正处于选举状态
  2. Following:Follower 节点所处的状态,Follower与 Leader处于数据同步状态
  3. Leading:Leader 所处状态,当前集群中有一个 Leader 为主进程
  • ZooKeeper启动时所有节点初始状态为Looking,这时集群会尝试选举出一个Leader节点,选举出的Leader节点切换为Leading状态;当节点发现集群中已经选举出Leader则该节点会切换到Following状态,然后和Leader节点保持同步;当Follower节点与Leader失去联系时Follower节点则会切换到Looking状态,开始新一轮选举;在ZooKeeper的整个生命周期中每个节点都会在Looking、Following、Leading状态间不断转换。
  • 选举出Leader节点后 ZAB 进入原子广播阶段,这时Leader为和自己同步每个节点 Follower 创建一个操作序列,一个时期一个 Follower 只能和一个Leader保持同步

阶段

  1. Election: 在 Looking状态中选举出 Leader节点,Leader的LastZXID总是最新的(只有lastZXID的节点才有资格成为Leade,这种情况下选举出来的Leader总有最新的事务日志)。在选举的过程中会对每个Follower节点的ZXID进行对比只有highestZXID的Follower才可能当选Leader
    • 每个Follower都向其他节点发送选自身为Leader的Vote投票请求,等待回复;
    • Follower接受到的Vote如果比自身的大(ZXID更新)时则投票,并更新自身的Vote,否则拒绝投票;
    • 每个Follower中维护着一个投票记录表,当某个节点收到过半的投票时,结束投票并把该Follower选为Leader,投票结束;
  2. Discovery:Follower 节点向准 Leader推送 FollwerInfo,该信息包含了上一周期的epoch,接受准 Leader 的 NEWLEADER 指令
  3. Sync:将 Follower 与 Leader的数据进行同步,由Leader发起同步指令,最终保持数据的一致性
  4. Broadcast:Leader广播 Proposal 与 Commit,Follower 接受 Proposal 与 commit。因为一个时刻只有一个Leader节点,若是更新请求,只能由Leader节点执行(若连到的是 Follower 节点,则需转发到Leader节点执行;读请求可以从Follower 上读取,若是要最新的数据,则还是需要在 Leader上读取)
    • 消息广播使用了TCP协议进行通讯所有保证了接受和发送事务的顺序性。广播消息时Leader节点为每个事务Proposal分配一个全局递增的ZXID(事务ID),每个事务Proposal都按照ZXID顺序来处理(Paxos 保证不了)
    • Leader节点为每一个Follower节点分配一个队列按事务ZXID顺序放入到队列中,且根据队列的规则FIFO来进行事务的发送。
  5. Recovery :根据Leader的事务日志对Follower 节点数据进行同步更新
    • 同步策略:
      1. SNAP :如果Follower数据太老,Leader将发送快照SNAP指令给Follower同步数据;
      2. DIFF :Leader发送从Follolwer.lastZXID到Leader.lastZXID议案的DIFF指令给Follower同步数据;
      3. TRUNC :当Follower.lastZXID比Leader.lastZXID大时,Leader发送从Leader.lastZXID到Follower.lastZXID的TRUNC指令让Follower丢弃该段数据;(当老Leader在Commit前挂掉,但是已提交到本地)
    • Follower将所有事务都同步完成后Leader会把该节点添加到可用Follower列表中;
    • Follower接收Leader的NEWLEADER指令,如果该指令中epoch比当前Follower的epoch小那么Follower转到Election阶段

7. Raft 算法

  • Raft 算法也是一种少数服从多数的算法,在任何时候一个服务器可以扮演以下角色之一:
    1. Leader:负责 Client 交互 和 log 复制,同一时刻系统中最多存在一个
    2. Follower:被动响应请求 RPC,从不主动发起请求 RPC
    3. Candidate : 由Follower 向Leader转换的中间状态
  • 在选举Leader的过程中,是有时间限制的,raft 将时间分为一个个 Term,可以认为是“逻辑时间”:
    1. 每个 Term中至多存在1个 Leader
    2. 某些 Term由于不止一个得到的票数一样,就会选举失败,不存在Leader。则会出现 Split Vote ,再由候选者发出邀票
    3. 每个 Server 本地维护 currentTerm
  • 选举过程:
    1. 自增 CurrentTerm,由Follower 转换为 Candidate,设置 votedFor 为自身,并行发起 RequestVote RPC,不断重试,直至满足下列条件之一为止:
      • 获得超过半数的Server的投票,转换为 Leader,广播 HeatBeat
      • 接收到 合法 Leader 的 AppendEnties RPC,转换为Follower
      • 选举超时,没有 Server选举成功,自增 currentTerm ,重新选举
    2. 当Candidate 在等待投票结果的过程中,可能会接收到来自其他Leader的 AppendEntries RPC ,如果该 Leader 的 Term 不小于本地的 Current Term,则认可该Leader身份的合法性,主动降级为Follower,反之,则维持 candida 身份继续等待投票结果
    3. Candidate 既没有选举成功,也没有收到其他 Leader 的 RPC (多个节点同时发起选举,最终每个 Candidate都将超时),为了减少冲突,采取随机退让策略,每个 Candidate 重启选举定时器
  • 日志更新问题:如果在日志复制过程中,发生了网络分区或者网络通信故障,使得Leader不能访问大多数Follwers了,那么Leader只能正常更新它能访问的那些Follower服务器,而大多数的服务器Follower因为没有了Leader,他们重新选举一个候选者作为Leader,然后这个Leader作为代表于外界打交道,如果外界要求其添加新的日志,这个新的Leader就按上述步骤通知大多数Followers,如果这时网络故障修复了,那么原先的Leader就变成Follower,在失联阶段这个老Leader的任何更新都不能算commit,都回滚,接受新的Leader的新的更新。
  • 流程:
    1. Client 发送command 命令给 Leader
    2. Leader追加日志项,等待 commit 更新本地状态机,最终响应 Client
    3. 若 Client超时,则不断重试,直到收到响应为止(重发 command,可能被执行多次,在被执行但是由于网络通信问题未收到响应)
      • 解决办法:Client 赋予每个 Command唯一标识,Leader在接收 command 之前首先检查本地log

9. paxos 算法与 raft 算法的差异

  1. raft强调是唯一leader的协议,此leader至高无上
  2. raft:新选举出来的leader拥有全部提交的日志,而 paxos 需要额外的流程从其他节点获取已经被提交的日志,它允许日志有空洞
  • 相同点:得到大多数的赞成,这个 entries 就会定下来,最终所有节点都会赞成

NWR模型

  • N: N个备份
  • W:要写入至少 w 份才认为成功
  • R : 至少读取 R 个备份
  • W+ R > N ——> R > N - W(未更新成功的) ,代表每次读取,都至少读取到一个最新的版本(更新成功的),从而不会读到一份旧数据
  • 问题:并非强一致性,会出现一些节点上的数据并不是最新版本,但却进行了最新的操作
  • 版本冲突问题:矢量钟 Vector Clock : 谁更新的我,我的版本号是什么(对于同一个操作者的同一操作,版本号递增)

参考资料:

http://www.tuicool.com/articles/IfQR3u3

http://blog.csdn.net/chen77716/article/details/7309915

http://www.infoq.com/cn/articles/distributed-system-transaction-processing/

http://www.jdon.com/artichect/raft.html

http://blog.csdn.net/cszhouwei/article/details/38374603

文章转自:
https://blog.csdn.net/followmyinclinations/article/details/52870418
发表在 consensus | 标签为 , , | 分布式事务与一致性算法 paxos & raft & zab已关闭评论

CGI、FastCGI、PHP-FPM

基础

在整个网站架构中,Web Server(如Apache)只是内容的分发者。举个栗子,如果客户端请求的是 index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。

如果请求的是 index.php,根据配置文件,Web Server知道这个不是静态文件,需要去找 PHP 解析器来处理,那么他会把这个请求简单处理,然后交给PHP解析器。

当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程,接下来再引出这些概念,就好理解多了,

  • CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。
  • FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。同样,SCGI 协议与 FastCGI 类似。
  • PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序。
  • PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理。

WEB 中,

  • Web Server 一般指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器,
  • Web Application 一般指PHP、Java、Asp.net等应用程序。

Module方式

在了解 CGI 之前,我们先了解一下Web server 传递数据的另外一种方法:PHP Module加载方式。以 Apache 为例,在PHP Module方式中,是不是在 Apache 的配置文件 httpd.conf 中加上这样几句:

# 加入以下2句
LoadModule php5_module D:/php/php5apache2_2.dll
AddType application/x-httpd-php .php

# 修改如下内容
<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

上面是 Windows 下安装php和apache环境后手动配置,在linux下源码安装大致是这样配置的:

# ./configure --with-mysql=/usr/local --with-apache=/usr/local/apache --enable-track-vars

所以,这种方式,他们的共同本质都是用 LoadModule 来加载 php5_module,就是把php作为apache的一个子模块来运行。当通过web访问php文件时,apache就会调用php5_module来解析php代码。

那么php5_module是怎么来将数据传给php解析器来解析php代码的呢?答案是通过sapi。

我们再来看一张图,详细的说说apache 与 php 与 sapi的关系:

从上面图中,我们看出了sapi就是这样的一个中间过程,SAPI提供了一个和外部通信的接口,有点类似于socket,使得PHP可以和其他应用进行交互数据(apache,nginx等)。php默认提供了很多种SAPI,常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI。

所以,以上的apache调用php执行的过程如下:

apache -> httpd -> php5_module -> sapi -> php

好了。apache与php通过php5_module的方式就搞清楚了吧!

这种模式将php模块安装到apache中,所以每一次apache结束请求,都会产生一条进程,这个进程就完整的包括php的各种运算计算等操作。

在上图中,我们很清晰的可以看到,apache每接收一个请求,都会产生一个进程来连接php通过sapi来完成请求,可想而知,如果一旦用户过多,并发数过多,服务器就会承受不住了。

而且,把mod_php编进apache时,出问题时很难定位是php的问题还是apache的问题。

CGI

CGI(Common Gateway Interface)全称是“通用网关接口”,WEB 服务器与PHP应用进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php、perl、tcl等。

WEB服务器会传哪些数据给PHP解析器呢?URL、查询字符串、POST数据、HTTP header都会有。所以,CGI就是规定要传哪些数据,以什么样的格式传递给后方处理这个请求的协议。仔细想想,你在PHP代码中使用的用户从哪里来的。

也就是说,CGI就是专门用来和 web 服务器打交道的。web服务器收到用户请求,就会把请求提交给cgi程序(如php-cgi),cgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi的工作原理。

CGI的好处就是完全独立于任何服务器,仅仅是做为中间分子。提供接口给apache和php。他们通过cgi搭线来完成数据传递。这样做的好处了尽量减少2个的关联,使他们2变得更独立。

但是CGI有个蛋疼的地方,就是每一次web请求都会有启动和退出过程,也就是最为人诟病的fork-and-execute模式,这样一在大规模并发下,就死翘翘了。

FastCGI介绍

FastCGI简单介绍

从根本上来说,FastCGI是用来提高CGI程序性能的。类似于CGI,FastCGI也可以说是一种协议

FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次。它还支持分布式的运算, 即 FastCGI 程序可以在网站服务器以外的主机上执行,并且接受来自其它网站服务器来的请求。

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中,并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中,并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail- Over特性等等。

FastCGI的工作原理

FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

  1. Web Server启动时载入FastCGI进程管理器(Apache Module或IIS ISAPI等)
  2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可建多个php-cgi),并等待来自Web Server的连接。
  3. 当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
  4. FastCGI子进程完成处理后,将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待,并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。 在CGI模式中,php-cgi在此便退出了。

FastCGI与CGI特点:

  1. 对于CGI来说,每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展,并重新初始化全部数据结构。而使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。
  2. 由于FastCGI是多进程,所以比CGI多线程消耗更多的服务器内存,php-cgi解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。

PHP-FPM介绍

要了解PHP-FPM,就得先说说PHP-CGI。

PHP-CGI就是PHP实现的自带的FastCGI管理器。 虽然是php官方出品,但是这丫的却一点也不给力,性能太差,而且也很麻烦不人性化,主要体现在:

  1. php-cgi变更php.ini配置后,需重启php-cgi才能让新的php-ini生效,不可以平滑重启。
  2. 直接杀死php-cgi进程,php就不能运行了。

上面2个问题,一直让很多人病垢了很久,所以很多人一直还是在用 Module 方式。 直到 2004年一个叫 Andrei Nigmatulin的屌丝发明了PHP-FPM ,这神器的出现就彻底打破了这种局面,这是一个PHP专用的 fastcgi 管理器,它很爽的克服了上面2个问题,而且,还表现在其他方面更表现强劲。

也就是说,PHP-FPM 是对于 FastCGI 协议的具体实现,他负责管理一个进程池,来处理来自Web服务器的请求。目前,PHP5.3版本之后,PHP-FPM是内置于PHP的

因为PHP-CGI只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理。所以就出现了一些能够调度 php-cgi 进程的程序,比如说由lighthttpd分离出来的spawn-fcgi。同样,PHP-FPM也是用于调度管理PHP解析器php-cgi的管理程序。

PHP-FPM通过生成新的子进程可以实现php.ini修改后的平滑重启。

总结

最后,我们来总结一下,这些技术经过不断的升级,可以解决什么问题(不然也不会升级嘛)。

所以,如果要搭建一个高性能的PHP WEB服务器,目前最佳的方式是Apache/Nginx + FastCGI + PHP-FPM(+PHP-CGI)方式

 

原文:https://www.awaimai.com/371.html

 

.

 

发表在 php | CGI、FastCGI、PHP-FPM已关闭评论

linux route

语法

route(选项)(参数)

直接在命令行下执行route命令来添加路由,不会永久保存,当网卡重启或者机器重启之后,该路由就失效了;可以在/etc/rc.local中添加route命令来保证该路由设置永久有效。

选项

-A:设置地址类型;
-C:打印将Linux核心的路由缓存;
-v:详细信息模式;
-n:不执行DNS反向查找,直接显示数字形式的IP地址;
-e:netstat格式显示路由表;
-net:到一个网络的路由表;
-host:到一个主机的路由表。

参数

Add:增加指定的路由记录;
Del:删除指定的路由记录;
Target:目的网络或目的主机;
gw:设置默认网关;
mss:设置TCP的最大区块长度(MSS),单位MB;
window:指定通过路由表的TCP连接的TCP窗口大小;
dev:路由记录所表示的网络接口。

实例

显示当前路由:

[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
112.124.12.0    *               255.255.252.0   U     0      0        0 eth1
10.160.0.0      *               255.255.240.0   U     0      0        0 eth0
192.168.0.0     10.160.15.247   255.255.0.0     UG    0      0        0 eth0
172.16.0.0      10.160.15.247   255.240.0.0     UG    0      0        0 eth0
10.0.0.0        10.160.15.247   255.0.0.0       UG    0      0        0 eth0
default         112.124.15.247  0.0.0.0         UG    0      0        0 eth1

[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
112.124.12.0    0.0.0.0         255.255.252.0   U     0      0        0 eth1
10.160.0.0      0.0.0.0         255.255.240.0   U     0      0        0 eth0
192.168.0.0     10.160.15.247   255.255.0.0     UG    0      0        0 eth0
172.16.0.0      10.160.15.247   255.240.0.0     UG    0      0        0 eth0
10.0.0.0        10.160.15.247   255.0.0.0       UG    0      0        0 eth0
0.0.0.0         112.124.15.247  0.0.0.0         UG    0      0        0 eth1

其中Flags为路由标志,标记当前网络节点的状态,Flags标志说明:

  • U Up表示此路由当前为启动状态。
  • H Host,表示此网关为一主机。
  • G Gateway,表示此网关为一路由器。
  • R Reinstate Route,使用动态路由重新初始化的路由。
  • D Dynamically,此路由是动态性地写入。
  • M Modified,此路由是由路由守护程序或导向器动态修改。
  • ! 表示此路由当前为关闭状态。

添加网关/设置网关:

route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0    #增加一条到达244.0.0.0的路由。

屏蔽一条路由:

route add -net 224.0.0.0 netmask 240.0.0.0 reject     #增加一条屏蔽的路由,目的地址为224.x.x.x将被拒绝。

删除路由记录:

route del -net 224.0.0.0 netmask 240.0.0.0
route del -net 224.0.0.0 netmask 240.0.0.0 reject

删除和添加设置默认网关:

route del default gw 192.168.120.240
route add default gw 192.168.120.240

 

route 命令的输出项说明

输出项 说明
Destination 目标网段或者主机
Gateway 网关地址,”*” 表示目标是本主机所属的网络,不需要路由
Genmask 网络掩码
Flags 标记。一些可能的标记如下:
U — 路由是活动的
H — 目标是一个主机
G — 路由指向网关
R — 恢复动态路由产生的表项
D — 由路由的后台程序动态地安装
M — 由路由的后台程序修改
! — 拒绝路由
Metric 路由距离,到达指定网络所需的中转数(linux 内核中没有使用)
Ref 路由项引用次数(linux 内核中没有使用)
Use 此路由项被路由软件查找的次数
Iface 该路由表项对应的输出接口

网关为0.0.0.0的网络通常是直连到网络设备上的,本地的直通路由。因为到自己的直连设备上是不需要网关的,所以0.0.0.0的网关地址是正常的。目的地址是0.0.0.0的路由是你的缺省网关。

 

 

 

 

..

 

 

发表在 linux | linux route已关闭评论

linux bridge vlan 架构方案实例

一、组网结构图如下:

1、SW交换机和HUB

1)、交换机连接HUB的端口为trunk模式,trunk vlan100,交换机上的外网网段为10.10.100.0/24,vlan为100 ,分配iptables服务器的IP是10.10.100.100,网关是10.10.100.254;
2)、HUB是一个纯hub,不能做任何的配置。

2、服务器A

  • A主机的eth0上联到HUB,把eth0划分成两个逻辑子端口eth0.10、eth0.20,eth0.10打上vlan10标签,eth0.20打上vlan20标签;
  • A主机里面运行两个虚拟机VM1和VM2;
  • 两台虚拟机在不同的网段,10.10.10.0/24  vlan10网关是10.10.10.254、10.10.20.0/24vlan20  网关是10.10.20.254;
  • 在主机A中建立两个bridge: br10、br20 ,br10关联端口eth0.10 ,br20关联端口eth0.20,br10的IP是10.10.10.1,br20的IP是10.10.20.1
  • VM1桥接到br10ip:10.10.10.11,VM2桥接到br20 ip:10.10.20.11;

3、服务器B1)、B主机的eth0上联到HUB,把eth0划分成两个逻辑子端口eth0.10、eth0.20,eth0.10打上vlan10标签,eth0.20打上vlan20标签;
2)、B主机里面运行两个虚拟机VM3和VM4;
3)、两台虚拟机在不同的网段,10.10.10.0/24  vlan10 网关是10.10.10.254、10.10.20.0/24 vlan20  网关是10.10.20.254;
4)、在主机B中建立两个bridge: br10、br20 ,br10关联端口eth0.10 ,br20关联端口eth0.20,br10的IP是10.10.10.2,br20的IP是10.10.20.2
5)、VM3桥接到br10 ip是10.10.10.12,VM2桥接到br20 ip是10.10.20.12;

4、IPtables服务器

1)、iptalbes服务器在这的作用是:让A、B服务器内的虚拟机出网nat作用、通过外网访问A、B虚拟机提供的web服务器。
2)、iptables服务器的eth0口,走虚拟机vlan10、vlan20的业务流量,所以需要通过eth0划分两个逻辑端口eth0.10、eth0.20,并且创建两个bridge:br10、br20,br10关联端口eth0.10,br20关联端口eth0.20,br10的ip地址是10.10.10.254,br20的ip地址是10.10.20.254。
3)、iptables服务器的eth1口作为外网出口接入hub,需要在eth1端口上配置IP10.10.100.100,网关配置为10.10.100.254,用vconfig命令给eth1打上vlan标签100。

5、实现需求    A、B服务器的虚拟机可以相互访问,虚拟机可以访问外网,A服务器提供的web管理界面可以通过外网访问。
二、网络层面设备配置1、交换机配置   把交换机和hub相连的端口配置为trunk端口,允许vlan 100通过。
2、服务器A的配置1)、安装vconfig包(redhat7.0一下版本默认带vconfig包)

yum install vconfig

2)、在内核加载802.1q模块

modprobe 8021q
lsmod |grep -i 8021q  (查看模块是否加载)

3)、配置物理网卡

sed  –i  's/ONBOOT=no/ONBOOT=yes/g'  /etc/sysconfig/network-scripts/ifcfg-eth0

sed –i 's/BOOTPROTO=dhcp/BOOTPROTO=static/g'/etc/sysconfig/network-scripts/ifcfg-eth0

3)、给物理接口添加vlan并配置vlan的属性

vconfig add eth0 10
config set_flag eth0.10 1 1
vconfig add eth0 20
config set_flag eth0.20 1 1

4)、添加eth0.10、eth0.20子接口并添加配置文件

touch /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'DEVICE=eth0.10' >> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'ONBOOT=yes'  >> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'BOOTPROTO=static' >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'TYPE=ethernet' >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'BRIDGE=br10'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10 #(把eth0.10加入br10)
touch /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'DEVICE=eth0.20' >> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'BOOTPROTO=static' >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'TYPE=ethernet' >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'BRIDGE=br20'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20 #(把eth0.20加入br20)

5)、配置bridge

touch/etc/sysconfig/network-scripts/ifcfg-br10
echo 'DEVICE=br10'  >> /etc/sysconfig/network-scripts/ifcfg-br10
echo 'ONBOOT=yes'  >> /etc/sysconfig/network-scripts/ifcfg-br10
echo 'BOOTPROTO=static'>> /etc/sysconfig/network-scripts/ifcfg-br10
echo 'TYPE=bridge' >>/etc/sysconfig/network-scripts/ifcfg-br10
touch/etc/sysconfig/network-scripts/ifcfg-br20
echo 'DEVICE=br10'  >> /etc/sysconfig/network-scripts/ifcfg-br20
echo 'ONBOOT=yes'  >> /etc/sysconfig/network-scripts/ifcfg-br20
echo 'BOOTPROTO=static'>> /etc/sysconfig/network-scripts/ifcfg-br20
echo 'TYPE=bridge' >>/etc/sysconfig/network-scripts/ifcfg-br20

6)、启动子接口和bridge接口

ifup eth0.10
ifup eth0.20
ifup br10
ifup br20

7)、给bridge接口配置IP
echo 'IPADDR=10.10.10.1'  >> /etc/sysconfig/network-scripts/ifcfg-br10

echo 'NETMASK=255.255.255.0'  >> /etc/sysconfig/network-scripts/ifcfg-br10

echo 'IPADDR=10.10.20.1'  >> /etc/sysconfig/network-scripts/ifcfg-br20

echo 'NETMASK= 255.255.255.0'  >> /etc/sysconfig/network-scripts/ifcfg-br20

8)、添加eth0.10 eth0.20到br10、br20
brctl addif br10  eth0.10
brctl addif br20  eth0.20
9)、重启网络

service network restart
10)、设置下次启动自动加载8021q 模块
echo 'VLAN=yes' >> /etc/sysconfig/network
echo 'modprobe 8021q'>>/etc/rc.local

11)、可以使用cat /proc/net/vlan/eth0.10查看eth0.10参数
3、服务器B的配置1)、安装vconfig包(redhat7.0一下版本默认带vconfig包)

yum install vconfig

2)、在内核加载802.1q模块

modprobe 8021q
lsmod |grep -i8021q  (查看模块是否加载)

3)、配置物理网卡

sed  –i  's/ONBOOT=no/ONBOOT=yes/g' /etc/sysconfig/network-scripts/ifcfg-eth0

sed –i 's/BOOTPROTO=dhcp/BOOTPROTO=static/g'/etc/sysconfig/network-scripts/ifcfg-eth0

3)、给物理接口添加vlan并配置vlan的属性

vconfig add eth010
config set_flageth0.10 1 1
vconfig add eth0 20
config set_flag eth0.20 1 1

4)、添加eth0.10、eth0.20子接口并添加配置文件

touch/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'DEVICE=eth0.10'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'TYPE=ethernet'>> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'BRIDGE=br10'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10 #(把eth0.10加入br10)
touch/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'DEVICE=eth0.20'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'TYPE=ethernet'>> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'BRIDGE=br20'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20 #(把eth0.20加入br20)

5)、配置bridge

touch /etc/sysconfig/network-scripts/ifcfg-br10
echo 'DEVICE=br10'  >>/etc/sysconfig/network-scripts/ifcfg-br10
echo 'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-br10
echo 'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-br10
echo 'TYPE=bridge' >> /etc/sysconfig/network-scripts/ifcfg-br10
touch /etc/sysconfig/network-scripts/ifcfg-br20
echo 'DEVICE=br10'  >>/etc/sysconfig/network-scripts/ifcfg-br20
echo 'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-br20
echo 'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-br20
echo 'TYPE=bridge' >>/etc/sysconfig/network-scripts/ifcfg-br20

6)、启动子接口和bridge接口

ifup eth0.10
ifup eth0.20
ifup br10
ifup br20

7)、给bridge接口配置IP
echo'IPADDR=10.10.10.2'  >> /etc/sysconfig/network-scripts/ifcfg-br10

echo 'NETMASK= 255.255.255.0' >> /etc/sysconfig/network-scripts/ifcfg-br10

echo'IPADDR=10.10.20.2'  >> /etc/sysconfig/network-scripts/ifcfg-br20

echo 'NETMASK= 255.255.255.0' >> /etc/sysconfig/network-scripts/ifcfg-br20

8)、添加eth0.10 eth0.20到br10、br20
brctladdif br10  eth0.10
brctladdif br20  eth0.20
9)、重启网络

service network restart
10)、设置下次启动自动加载 8021q 模块
echo 'VLAN=yes' >> /etc/sysconfig/network
echo 'modprobe 8021q' >>/etc/rc.local

服务器A和服务器B的网络配置只有bridge上的IP不同
4、IPtables服务器的配置(1)、服务器eth0口的配置1)、安装vconfig包(redhat7.0一下版本默认带vconfig包)

yum install vconfig

2)、在内核加载802.1q模块

modprobe 8021q
lsmod |grep -i8021q  (查看模块是否加载)

3)、配置物理网卡

sed  –i  's/ONBOOT=no/ONBOOT=yes/g' /etc/sysconfig/network-scripts/ifcfg-eth0

sed –i 's/BOOTPROTO=dhcp/BOOTPROTO=static/g'/etc/sysconfig/network-scripts/ifcfg-eth0

3)、给物理接口添加vlan并配置vlan的属性

vconfig add eth010
config set_flageth0.10 1 1
vconfig add eth0 20
config set_flag eth0.20 1 1

4)、添加eth0.10、eth0.20子接口并添加配置文件

touch/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'DEVICE=eth0.10'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo 'TYPE=ethernet'>> /etc/sysconfig/network-scripts/ifcfg-eth0.10
echo'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.10
touch/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'DEVICE=eth0.20'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'ONBOOT=yes'  >> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'TYPE=ethernet'>> /etc/sysconfig/network-scripts/ifcfg-eth0.20
echo'VLAN=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20

5)、启动子接口

ifup eth0.10
ifup eth0.20

6)、给子接口接口配置IP
echo'IPADDR=10.10.10.254'  >> /etc/sysconfig/network-scripts/ifcfg-eth0.10

echo 'NETMASK= 255.255.255.0' >> /etc/sysconfig/network-scripts/ifcfg-eth0.10

echo'IPADDR=10.10.20.254'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20
echo 'NETMASK= 255.255.255.0'  >>/etc/sysconfig/network-scripts/ifcfg-eth0.20

7)、重启网络

service network restart
8)、设置下次启动自动加载 8021q 模块
echo 'VLAN=yes' >> /etc/sysconfig/network
echo 'modprobe 8021q' >>/etc/rc.local

(2)、服务器eth1口的配置1)、配置物理网卡

sed  –i  's/ONBOOT=no/ONBOOT=yes/g' /etc/sysconfig/network-scripts/ifcfg-eth1

sed –i 's/BOOTPROTO=dhcp/BOOTPROTO=static/g'/etc/sysconfig/network-scripts/ifcfg-eth1

2)、给物理接口添加vlan并配置vlan的属性

vconfig add eth1100
config set_flageth1.100 1 1

3)、添加eth1.100子接口并添加配置文件

touch /etc/sysconfig/network-scripts/ifcfg-eth1.100
echo 'DEVICE=eth1.100'  >> /etc/sysconfig/network-scripts/ifcfg-eth1.100
echo'ONBOOT=yes'  >>/etc/sysconfig/network-scripts/ifcfg-eth1.100
echo'BOOTPROTO=static' >> /etc/sysconfig/network-scripts/ifcfg-eth1.100
echo 'TYPE=ethernet'>> /etc/sysconfig/network-scripts/ifcfg-eth1.100
echo'VLAN=yes'  >> /etc/sysconfig/network-scripts/ifcfg-eth1.100

4)、启动子接口

ifup eth1.100

5)、给子接口接口配置IP
echo'IPADDR=10.10.100.100'  >>/etc/sysconfig/network-scripts/ifcfg-eth1.100

echo 'NETMASK= 255.255.255.0' >> /etc/sysconfig/network-scripts/ifcfg-eth1.100
echo 'GATEWAY= 10.10.100.254' >> /etc/sysconfig/network-scripts/ifcfg-eth1.100

6)、重启网络

service network restart
7)、设置下次启动自动加载 8021q 模块
echo'VLAN=yes' >> /etc/sysconfig/network
echo 'modprobe 8021q' >>/etc/rc.local

(3)、让服务器A、B内的虚拟机出网

iptables -t nat -A POSTROUTING -s10.10.10.0/24 -o eth1.100 -j MASQUERADE

iptables-t nat -A POSTROUTING -s 10.10.20.0/24 -o eth1.100 -j MASQUERADE

echo 1 > /proc/sys/net/ipv4/ip_forward

(4)、外网设备要访问vm1的80端口

iptables -t nat -A PREROUTING -p tcp -d 10.10.100.100 --dport 80-j DNAT --to-destination 10.10.10.11:80

把外网设备访问10.10.100.100的80端口映射到vm1设备的80端口

 

原文:
http://www.iyunv.com/thread-51063-1-1.html

..
发表在 linux | linux bridge vlan 架构方案实例已关闭评论

桃之妖妖,灼灼其华

玲珑通透

 

 

发表在 article | 已关闭评论

Protobuf

Protobuf消息定义

 

要通信,必须有协议,否则双方无法理解对方的码流。在protobuf中,协议是由一系列的消息组成的。因此最重要的就是定义通信时使用到的消息格式。

消息由至少一个字段组合而成,类似于C语言中的结构。每个字段都有一定的格式。

字段格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]

①.限定修饰符包含 required\optional\repeated

Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。

Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。

Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。

 

②.数据类型

Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型.

protobuf 数据类型

描述 打包 C++语言映射
bool 布尔类型 1字节 bool
double 64位浮点数 N double
float 32为浮点数 N float
int32 32位整数、 N int
uin32 无符号32位整数 N unsigned int
int64 64位整数 N __int64
uint64 64为无符号整 N unsigned __int64
sint32 32位整数,处理负数效率更高 N int32
sing64 64位整数 处理负数效率更高 N __int64
fixed32 32位无符号整数 4 unsigned int32
fixed64 64位无符号整数 8 unsigned __int64
sfixed32 32位整数、能以更高的效率处理负数 4 unsigned int32
sfixed64 64为整数 8 unsigned __int64
string 只能处理 ASCII字符 N std::string
bytes 用于处理多字节的语言字符、如中文 N std::string
enum 可以包含一个用户自定义的枚举类型uint32 N(uint32) enum
message 可以包含一个用户自定义的消息类型 N object of class

N 表示打包的字节并不是固定。而是根据数据的大小或者长度。

例如int32,如果数值比较小,在0~127时,使用一个字节打包。

关于枚举的打包方式和uint32相同。

关于message,类似于C语言中的结构包含另外一个结构作为数据成员一样。

关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.

③.字段名称

字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。

protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.

④.字段编码值

有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。

编码值的取值范围为 1~2^32(4294967296)。

其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16.

1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。

protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。

消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。

建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。

 

⑤.默认值。当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。

关于import

protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。

关于package

避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。

关于message

支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。

关于enum

枚举的定义和C++相同,但是有一些限制。

枚举值必须大于等于0的整数。

使用分号(;)分隔枚举变量而不是C++语言中的逗号(,)

eg.

enum VoipProtocol

{

H323 = 1;

SIP  = 2;

MGCP = 3;

H248 = 4;

}

 

Protobuf与Thrift

 

数据类型

protobuf thrift protobuf thrift protobuf thrift protobuf thrift

double double float byte i16
int32 i32 int64 i64 uint32 uint64
sint32 sint64 fixed32 fixed64
sfixed32 sfixed64 bool bool string string
bytes binary message struct enum enum service service

综合对比

protobuf thrift
功能特性 主要是一种序列化机制 提供了全套RPC解决方案,包括序列化机制、传输层、并发处理框架等
支持语言 C++/Java/Python C++, Java, Python, Ruby, Perl, PHP, C#, Erlang, Haskell
易用性 语法类似,使用方式等类似
生成代码的质量 可读性都还过得去,执行效率另测
升级时版本兼容性 均支持向后兼容和向前兼容
学习成本 功能单一,容易学习 功能丰富、学习成本高
文档&社区 官方文档较为丰富,google搜索protocol buffer有2000W+结果,google group被墙不能访问 官方文档较少,没有API文档,google搜索apache thrift仅40W结果,邮件列表不怎么活跃

性能对比
由于thrift功能较protobuf丰富,因此单从序列化机制上进行性能比较,按照序列化后字节数、序列化时间、反序列化时间三个指标进行,对thrift的二进制、压缩、protobuf三种格式进行对比。

测试方法:取了15000+条样本数据,分别写了三个指标的测试程序,在我自己的电脑上执行,其中时间测试循环1000次,总的序列化/反序列化次数1500W+。

平均字节数

thrift二进制 535
thrift压缩 473
protobuf 477

序列化(1500W次)时间(ms)

thrift二进制 306034
thrift压缩 304256
protobuf 177652

反序列化(1500W次)时间(ms)

thrift二进制 287972
thrift压缩 315991
protobuf 157192

thrift的时间测试可能不是很准,由于thrift产生代码的复杂性,编写的测试代码为了适应其接口,在调用堆栈上可能有一些额外开销

 

原文: http://aoyouzi.iteye.com/blog/2288328

 

 

发表在 protocol | Protobuf已关闭评论

Intent

Intent组件虽然不是四大组件,但却是连接四大组件的桥梁,学习好这个知识,也非常的重要。

一、什么是Intent

1、Intent的概念:

  • Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity, service和broadcast receiver之间的交互。Intent这个英语单词的本意是“目的、意向、意图”。
  • Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来响应。

activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,不需要通过Intent。我们来看下面这个图就知道了:

如果Activity1需要和Activity2进行联系,二者不需要直接联系,而是通过Intent作为桥梁。通俗来讲,Intnet类似于中介、媒婆的角色。

 

2、对于向这三种组件发送intent有不同的机制:

  • 使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
  • 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
  • 将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver。

二、Intent的相关属性:

  • Intent由以下各个组成部分:
  • component(组件):目的组件
  • action(动作):用来表现意图的行动
  • category(类别):用来表现动作的类别
  • data(数据):表示与动作要操纵的数据
  • type(数据类型):对于data范例的描写
  • extras(扩展信息):扩展信息
  • Flags(标志位):期望这个意图的运行模式

Intent类型分为显式Intent(直接类型)、隐式Intent(间接类型)。官方建议使用隐式Intent。上述属性中,component属性为直接类型,其他均为间接类型。

相比与显式Intent,隐式Intnet则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。

Activity 中 Intent Filter 的匹配过程 :

 

1、component(组件):目的组件

Component属性明确指定Intent的目标组件的类名称。(属于直接Intent)

2、Action(动作):用来表现意图的行动

当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写” 一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。

Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 <intent-filter >节点指定一个 Action列表用于标识 Activity 所能接受的“动作”。

3、category(类别):用来表现动作的类别

Category属性也是作为<intent-filter>子元素来声明的。例如:

<intent-filter>

<action android:name="com.vince.intent.MY_ACTION"></action>

<category android:name="com.vince.intent.MY_CATEGORY"></category>

<category android:name="android.intent.category.DEFAULT"></category>

</intent-filter>

4、data(数据):表示与动作要操纵的数据

  • Data属性是Android要访问的数据,和action和Category声明方式相同,也是在<intent-filter>中。
  • 多个组件匹配成功显示优先级高的; 相同显示列表。

Data是用一个uri对象来表示的,uri代表数据的地址,属于一种标识符。

5、type(数据类型):对于data范例的描写

如果Intent对象中既包含Uri又包含Type,那么,在<intent-filter>中也必须二者都包含才能通过测试。

Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。

data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果想要两个属性同时设置,要使用Intent.setDataAndType()方法。

6、extras(扩展信息):扩展信息

是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个

动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

7、Flags(标志位):期望这个意图的运行模式

一个程序启动后系统会为这个程序分配一个task供其使用,另外同一个task里面可以拥有不同应用程序的activity。那么,同一个程序能不能拥有多个task?这就涉及到加载activity的启动模式,这个需要单独讲一下。

注:android中一组逻辑上在一起的activity被叫做task,自己认为可以理解成一个activity堆栈

 

 

..

发表在 android | Intent已关闭评论

MQTT 协议 Client ID 长度不能超过23个字符

MqttException: MQIsdp ClientId > 23 bytes

ClientId的长度大于23时,无法链接MQTT服务器。

协议要求:客户端标识符(Client ID)是介于1和23个字符长度,客户端到服务器的唯一标识。

它必须在搜有客户端连接到一台服务器是唯一的,是在处理QoS级别1和2的消息ID中的关键。

如果客户端ID包含23个字符,服务器响应CONNECT消息,通过一个CONNACK,返回码2:标识符被拒绝。

英文原版的协议中是这样描述的:

 

..

 

发表在 mq | MQTT 协议 Client ID 长度不能超过23个字符已关闭评论

fstab

FSTAB 列描述

第一列:Device:磁盘设备文件或者该设备的Label或者UUID

查看UUID方式

blkid

使用设备名和label及uuid作为标识的不同

使用设备名称(/dev/sda)来挂载分区时是被固定死的,一旦磁盘的插槽顺序发生了变化,就会出现名称不对应的问题。因为这个名称是会改变的。

使用label挂载就不用担心插槽顺序方面的问题。不过要随时注意你的Label name。

使用UUID,每个分区被格式化以后都会有一个UUID作为唯一的标识号。使用uuid挂载的话就不用担心会发生错乱的问题了。

 

第二列:Mount point:设备的挂载点,就是你要挂载到哪个目录下。

第三列:filesystem:磁盘文件系统的格式,包括ext2、ext3、reiserfs、nfs、vfat等

第四列:parameters:文件系统的参数

Async/sync

设置是否为同步方式运行,默认为async

auto/noauto

 当下载mount -a 的命令时,此文件系统是否被主动挂载。默认为auto

rw/ro

 是否以以只读或者读写模式挂载

exec/noexec

 限制此文件系统内是否能够进行"执行"的操作

user/nouser

是否允许用户使用mount命令挂载

suid/nosuid

是否允许SUID的存在

Usrquota

启动文件系统支持磁盘配额模式

Grpquota

启动文件系统对群组磁盘配额模式的支持

Defaults

同事具有rw,suid,dev,exec,auto,nouser,async等默认参数的设置

 

第五列:能否被dump备份命令作用:dump是一个用来作为备份的命令。通常这个参数的值为0或者1

         0

代表不要做dump备份

         1

代表要每天进行dump的操作

         2

代表不定日期的进行dump操作

 

第六列:是否检验扇区:开机的过程中,系统默认会以fsck检验我们系统是否为完整(clean)。

0

不要检验

1

最早检验(一般根目录会选择)

2

1级别检验完成之后进行检验

 

 

 

 

..

 

发表在 linux | fstab已关闭评论

linux command / 硬件配置命令

系统
# uname -a # 查看内核/操作系统/CPU信息
# head -n 1 /etc/issue # 查看操作系统版本
# cat /proc/cpuinfo # 查看CPU信息
# hostname # 查看计算机名
# lspci -tv # 列出所有PCI设备
# lsusb -tv # 列出所有USB设备
# lsmod # 列出加载的内核模块
# env # 查看环境变量

资源
# free -m # 查看内存使用量和交换区使用量
# df -h # 查看各分区使用情况
# du -sh <目录名> # 查看指定目录的大小
# grep MemTotal /proc/meminfo # 查看内存总量
# grep MemFree /proc/meminfo # 查看空闲内存量
# uptime # 查看系统运行时间、用户数、负载
# cat /proc/loadavg # 查看系统负载

磁盘和分区
# mount | column -t # 查看挂接的分区状态
# fdisk -l # 查看所有分区
# swapon -s # 查看所有交换分区
# hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备)
# dmesg | grep IDE # 查看启动时IDE设备检测状况

网络
# ifconfig # 查看所有网络接口的属性
# iptables -L # 查看防火墙设置
# route -n # 查看路由表
# netstat -lntp # 查看所有监听端口
# netstat -antp # 查看所有已经建立的连接
# netstat -s # 查看网络统计信息

进程
# ps -ef # 查看所有进程
# top # 实时显示进程状态

用户
# w # 查看活动用户
# id <用户名> # 查看指定用户信息
# last # 查看用户登录日志
# cut -d: -f1 /etc/passwd # 查看系统所有用户
# cut -d: -f1 /etc/group # 查看系统所有组
# crontab -l # 查看当前用户的计划任务

服务
# chkconfig --list # 列出所有系统服务
# chkconfig --list | grep on # 列出所有启动的系统服务

程序
# rpm -qa # 查看所有安装的软件包

其他常用命令整理如下:
查看主板的序列号:dmidecode | grep -i 'serial number'
用硬件检测程序kuduz探测新硬件:service kudzu start ( or restart)
查看CPU信息:cat /proc/cpuinfo [dmesg | grep -i 'cpu'][dmidecode -t processor]
查看内存信息:cat /proc/meminfo [free -m][vmstat]
查看板卡信息:cat /proc/pci
查看显卡/声卡信息:lspci |grep -i 'VGA'[dmesg | grep -i 'VGA']
查看网卡信息:dmesg | grep -i 'eth'[cat /etc/sysconfig/hwconf | grep -i eth][lspci | grep -i 'eth']
查看PCI信息:lspci (相比cat /proc/pci更直观)
查看USB设备:cat /proc/bus/usb/devices
查看键盘和鼠标:cat /proc/bus/input/devices
查看系统硬盘信息和使用情况:fdisk & disk – l & df
查看各设备的中断请求(IRQ):cat /proc/interrupts
查看系统体系结构:uname -a
查看及启动系统的32位或64位内核模式:isalist –v [isainfo –v][isainfo –b]
查看硬件信息,包括bios、cpu、内存等信息:dmidecode
测定当前的显示器刷新频率:/usr/sbin/ffbconfig –rev ?
查看系统配置:/usr/platform/sun4u/sbin/prtdiag –v
查看当前系统中已经应用的补丁:showrev –p
显示当前的运行级别:who –rH
查看当前的bind版本信息:nslookup –class=chaos –q=txt version.bind
查看硬件信息:dmesg | more
显示外设信息, 如usb,网卡等信息:lspci
查看已加载的驱动:
lsnod
lshw
查看当前处理器的类型和速度(主频):psrinfo -v
打印当前的OBP版本号:prtconf -v
查看硬盘物理信息(vendor, RPM, Capacity):iostat –E
查看磁盘的几何参数和分区信息:prtvtoc /dev/rdsk/c0t0d0s
显示已经使用和未使用的i-node数目:
df –F ufs –o i
isalist –v
对于“/proc”中文件可使用文件查看命令浏览其内容,文件中包含系统特定信息:
主机CPU信息:Cpuinfo
主机DMA通道信息:Dma
文件系统信息:Filesystems
主机中断信息:Interrupts
主机I/O端口号信息:Ioprots
主机内存信息:Meninfo
Linux内存版本信息:Version

备注: proc – process information pseudo-filesystem 进程信息伪装文件系统

 

 

发表在 linux | linux command / 硬件配置命令已关闭评论

Ubuntu安装Intel e1000e千兆网卡

Ubuntu安装Intel e1000e千兆网卡,HP EliteDesk 880 G2安装Ubuntu系统,需要手动安装网卡驱动
注:此方法已经在惠普HP EliteDesk 880 G2 TWR台式机测试正常,网卡是:Intel Ethernet Connection I219-V

在Intel网站直接下载的Linux驱动是e1000e-3.3.5.tar(版本可能会有改变),这个压缩包里面没有编译好的.ko的文件,需要在Linux系统下编译之后才能使用

驱动安装步骤:
1、把驱动tar文件拷贝到用户自己定义的目录中

2、用tar命令解这个压缩包
tar -xzvf e1000e-3.3.5.tar.gz

3、切换到驱动的src目录下
cd e1000e-3.3.5/src/

4、编译驱动模块
make

5、安装模块
make install

6、这个二进制元将被安装到如下位置
cp e1000e.ko /lib/modules/[KERNEL_VERSION]/kernel/drivers/net/ethernet/e1000e.ko
cp e1000e.ko /lib/modules/3.13.0-32-generic/kernel/drivers/net/ethernet/e1000e.ko
以上的路径是默认的安装位置,在某些linux版本中可能是其他位置,具体信息可以查看在驱动的tar压缩包中的ldistrib.txt文件

7、安装模块
#insmod /lib/modules/3.13.0-32-generic/kernel/drivers/net/ethernet/e1000e.ko
insmod e1000e
modprobe e1000e

8、设定网卡IP地址:
ifconfig ethx x是网卡接口的号

...

 

发表在 linux | Ubuntu安装Intel e1000e千兆网卡已关闭评论

kvm xml configuration examples

 

<domain type='kvm'>
<name>win7-32</name>
<memory>1048576</memory>
<currentMemory>1048576</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>hvm</type>
<boot dev='cdrom'/>
<boot dev = 'hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='localtime'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/windows-virtio/win7-32.img'/>
<target dev='hda' bus='ide'/>
</disk>
<interface type='bridge'>
<source bridge='br0'/>
<mac address="00:16:3e:5d:aa:a9"/>
</interface>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen = '0.0.0.0' keymap='en-us'/>
</devices>
</domain>

 

 

 

 

发表在 virtual machine | kvm xml configuration examples已关闭评论

MAC地址厂商分配表

MAC 对照表可从ieee获得

http://standards-oui.ieee.org/oui/oui.txt

。。。。。

这个MAC对照表资源是从wireshark源码中获取的。
每块网卡都有一个MAC地址,MAC地址是一个6字节、也即48bit的数据。前3字节称为OUI,是由IEEE组织注册给网络设备生产商的;每个厂商拥有一个或多个OUI,彼此不同。后三字节则是由网络设备生产商分配给自己生产的每一个拥有MAC地址的设备,互不重复。
原理就是根据MAC地址前3字节来判断的,前3个字节、对应制造商的名称
此TXT资源是MAC前3字节与对应制造商的名称的对应关系表,如下所示:
000000 Xerox
000001 Xerox
000002 Xerox
000003 Xerox
000004 Xerox
000005 Xerox
000006 Xerox
000007 Xerox
000008 Xerox
000009 Xerox
00000A Omron Tateisi Electronics CO.
00000B Matrix
。。。。。。
001110 Maxanna Technology Co.
001111 Intel
001112 Honeywell Cmss
。。。。。。
001301 IronGate S.L.
001302 Intel Corporate
001303 GateConnect Technologies GmbH
001838 PanAccess Communications
001839 Cisco-Linksys
00183A Westell Technologies
00183B Cenits Co.
。。。。。。
001D09 Dell
001D0A Davis Instruments
001D0B Power Standards Lab
001D0C MobileCompia
。。。。。。
005055 Doms A/S
005056 VMWare
005057 Broadband Access Systems
有19037个不同制造商,见资源文件txt
Wireshark解析MAC地址时会把前三个字节解析为一个公司的名字。
例如:
MAC Address: 00:1D:09:14:D2:7E  (Dell)
MAC Address: 00:1E:4F:E7:FE:F9   (Dell)
MAC Address: 00:13:02:81:7C:36   (Intel Corporate)
MAC Address: 00:11:11:74:02:72    (Intel)
MAC Address: 00:1D:72:8C:8B:96   (Wistron)
MAC Address: 00:18:39:84:8B:84    (Cisco-Linksys)
MAC Address: 00:50:56:C0:00:01    (VMWare)                        



..
虚拟化:

在VM的世界中,每一台拥有虚拟NIC(网卡)的设备当然也拥有MAC地址。
这虚拟网卡的MAC地址,当然也是按照规定,前三字节为OUI,后三字节逐一分配给每个设备。
由于虚拟网卡的”制造商“是VMware,XenSource,微软 等虚拟平台软件的生产商,OUI当然就分配给了他们。

VMware VM所使用的OUI
按照VMware ESX 3的[Server Configuration Guide ]的说法,VMware的使用下面的三个OUI作为VM的MAC地址:
00:0C:29 – 用于自动生成的MAC地址
00:50:56 – 用于手动设置的MAC地址
00:05:69 – 曾经用于旧版本的VM(大约是在ESX 1.5的时代),在ESX 3中已经不再使用
但是在实际应用中,发现00:50:56这一MAC地址段并不是完全用于手动设置的MAC地址:
00:50:56:00:00:00 – 00:50:56:3F:FF:FF
这一段MAC地址可以用于手动设置的MAC地址
00:50:56:40:00:00 – 00:50:56:FF:FF:FF

MAC地址的生成
OUI有了,后三字节如何生成呢?要知道虚拟机是经常被创建和销毁的,这一点不像实体PC。网卡生产商可以计算每年生产多少块网卡,从而为每块网卡分配不同的MAC地址; VMware却不可能计算出每年有多少台VM、有多少块虚拟网卡被创建。
VMware ESX Server的算法是,使用散列算法,通过VM的UUID来生成MAC地址。VM的UUID是每一台VM特有的、128bit的ID,是由ESX Server硬件SMBIOS的UUID、加上VM的路径生成的。因此,一台虚拟机的虚拟网卡的MAC地址就与下面四个因素有关:
VMware的OUI
Host (ESX Server)的SMBIOS中的UUID
VM在服务器上的路径
网卡的实体名 (Entity Name),用来确保同一VM上的不同网卡有不同的MAC地址

 

..

发表在 network | MAC地址厂商分配表已关闭评论