用友软件首页

IPVS(也叫LVS)的源码分析之persistent参数

2016-1-14 0:0:0 wondial

IPVS(也叫LVS)的源码分析之persistent参数

IPVS(也叫LVS)的源码分析之persistent参数

最近在用 LVS做 LB,发现一个问题客户端总是出现session丢失问题,采用常用配置,均衡策略使用wlc, 看了一下wlc的策略相同的客户端都有可能轮训到不同的后台机器,在后台服务器上并没有对session进行复制,那样的却会导致客户端访问不同的服务器而导致在session丢失。

本简单的以为通过调整均衡策略就可以确保对同一客户端映射到相同的服务器,均衡策略参考(点击打开链接),而策略里面只有Source Hashing Scheduling 看起来可以达到这个目的,但是这个策略并不是推荐的策略。

在查看ipvsadmin的参数的时候,发现了参数-p,

-p, --persistent [timeout]:设置持久连接,这个模式可以使来自客户的多个请求被送到同一个真实服务器

感觉-p 参数和Source Hashing Scheduling 的策略有点类似,还是看代码来解决问题

IPVS也叫LVS

LVS 是属于内核模块中的,代码直接就可以在内核代码中找到,在内核中的名字是IPVS,我们下面还是以IPVS来称呼

Ipvs 的代码就挂载在/net/netfilter/ipvs中,在这里我们也可以看出IPVS是基于Netfilter框架实现的内核模块,linux 中的netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上登记了一些处理函数进行处理(如包过滤,NAT等,甚至可以是用户自定义的功能)。

Netfilter实现

Netfilter的状态图:


而Ipvs 在Netfilter中的几个状态中注册了钩子函数

static struct nf_hook_ops ip_vs_ops[] __read_mostly = {/* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be * applied to IPVS. */{.hook= ip_vs_in,.owner= THIS_MODULE,.pf= PF_INET,.hooknum        = NF_INET_LOCAL_IN,.priority       = 100,},/* After packet filtering, change source only for VS/NAT */{.hook= ip_vs_out,.owner= THIS_MODULE,.pf= PF_INET,.hooknum        = NF_INET_FORWARD,.priority       = 100,},/* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */{.hook= ip_vs_forward_icmp,.owner= THIS_MODULE,.pf= PF_INET,.hooknum        = NF_INET_FORWARD,.priority       = 99,},/* Before the netfilter connection tracking, exit from POST_ROUTING */{.hook= ip_vs_post_routing,.owner= THIS_MODULE,.pf= PF_INET,.hooknum        = NF_INET_POST_ROUTING,.priority       = NF_IP_PRI_NAT_SRC-1,},

而均衡策略主要实现在状态NF_INET_LOCAL_IN所对应的钩子函数ip_vs_in

IPVS中的2个结构体

1. ip_vs_conn 里面记录了客户端的地址,IPVS 所建立的虚拟地址,对应到真实的服务器的地址

2. ip_vs_protocol 记录在不同的协议(TCP, UDP)中的不同的钩子函数,比如使用什么类型的调度,什么函数接受数据

struct ip_vs_protocol ip_vs_protocol_tcp = {.name ="TCP",.protocol =IPPROTO_TCP,.num_states =IP_VS_TCP_S_LAST,.dont_defrag =0,.appcnt =ATOMIC_INIT(0),.init =ip_vs_tcp_init,.exit =ip_vs_tcp_exit,.register_app =tcp_register_app,.unregister_app =tcp_unregister_app,.conn_schedule =tcp_conn_schedule,.conn_in_get =tcp_conn_in_get,.conn_out_get =tcp_conn_out_get,.snat_handler =tcp_snat_handler,.dnat_handler =tcp_dnat_handler,.csum_check =tcp_csum_check,.state_name =tcp_state_name,.state_transition =tcp_state_transition,.app_conn_bind =tcp_app_conn_bind,.debug_packet =ip_vs_tcpudp_debug_packet,.timeout_change =tcp_timeout_change,.set_state_timeout =tcp_set_state_timeout,};

这是一个TCP下的ip_vs_protocol 的结构体,里面重要的是conn_in_get 函数也是在钩子函数ip_vs_in里调用的
static unsigned intip_vs_in(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){...pp = ip_vs_proto_get(iph.protocol);if (unlikely(!pp))return NF_ACCEPT;/* * Check if the packet belongs to an existing connection entry */cp = pp->conn_in_get(af, skb, pp, &iph, iph.len, 0);...}
我们已常见的TCP为例,最终调用了函数 tcp_conn_in_get
ip_vs_conn的全局数组ip_vs_conn_tab和链表c_list

这是一张全局的ip_vs_conn数组,保存这所有的以连接。通过客户端ip,port算出的hash,来计算到保存的 ip_vs_conn数组。

ip_vs_conn本身也保存一个链表c_list,这是个链表结构保存ip_vs_conn

初始化

在IPVS初始化的时候,就初始化了数组的大小,大小是不可变的(1<<12 )4096

当客户端hash算出相同的时候,通过遍历ip_vs_conn里面的c_list链表找到匹配的客户端(地址和端口相同)

如果找不到对应的ip_vs_conn, 这时候才调用

if (!pp->conn_schedule(af, skb, pp, &v, &cp))return v;
而对tcp 中的conn_schedule 的钩子函数就是tcp_conn_schedule,也就是我们前面说到的调度算法的核心函数

static inttcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,  int *verdict, struct ip_vs_conn **cpp){struct ip_vs_service *svc;struct tcphdr _tcph, *th;struct ip_vs_iphdr iph;ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph);if (th == NULL) {*verdict = NF_DROP;return 0;}if (th->syn &&    (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr,     th->dest))) {if (ip_vs_todrop()) {/* * It seems that we are very loaded. * We have to drop this packet :( */ip_vs_service_put(svc);*verdict = NF_DROP;return 0;}/* * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */*cpp = ip_vs_schedule(svc, skb); //调用了ip_vs_scheduleif (!*cpp) {*verdict = ip_vs_leave(svc, skb, pp);return 0;}ip_vs_service_put(svc);}return 1;}

函数ip_vs_schedule

struct ip_vs_conn *ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb){.../* *    Persistent service */if (svc->flags & IP_VS_SVC_F_PERSISTENT)return ip_vs_sched_persist(svc, skb, pptr);/* *    Non-persistent service */if (!svc->fwmark && pptr[1] != svc->port) {if (!svc->port)pr_err("Schedule: port zero only supported "       "in persistent services, "       "check your ipvs configuration\n");return NULL;}<span style="white-space:pre"></span>....return cp;}
我们看到了IP_VS_SVC_F_PERSISTENT, 也就是参数persistent

参数persistent 的实现创建ip_vs_conn 模版

保证在一定的时间内相同的客户端ip还是连接原来的服务器,那就意味着需要保留原来的客户端ip的上次的连接的真实服务器。

在IPVS里并没有生成另一个数组去保留这个状态,而是引入了一个ip_vs_conn 模版,而这个ip_vs_conn 模版仍旧保存在前面提到的全局表中的ip_vs_conn_tab

既然保存在同一个全局表,那么这个模版和普通的ip_vs_conn有什么区别?很简单,这里只要设置客户端的port 为0,而把连到真实的server的IP 保存到ip_vs_conn中去

具体实现参考函数:ip_vs_sched_persist

什么时候清除ip_vs_conn 模版?

-p 参数有指定时间,ip_vs_conn结构体中存在一个timer和timeout的时间,在函数新建连接的时候,设置了timer的执行函数ip_vs_conn_expire

struct ip_vs_conn *ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,       const union nf_inet_addr *vaddr, __be16 vport,       const union nf_inet_addr *daddr, __be16 dport, unsigned flags,       struct ip_vs_dest *dest){<span style="white-space:pre"></span>......setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);......return cp;}

函数ip_vs_conn_expire里从ip_vs_conn_tab移除了ip_vs_conn超时的模版

而在ip_vs_sched_persist 函数里,当每次创建新的连接的时候,同时也更新了ip_vs_conn模版的timer的触发时间(当前时间+-p 参数的timeout时间),实现在函数ip_vs_conn_put中。


完整流程图



IPVS的debug日志

需要从新编译内核,设置config 里的参数

CONFIG_IP_VS_DEBUG=Y

编译后,还要修改参数

/proc/sys/net/ipv4/vs/debug_level

设置为12 ,日志打印到dmesg中

IPVS ip_vs_conn_tab 里的entry

内容可以通过 /proc/net/ip_vs_conn_entries 访问


如果您的问题还没有解决,可以到 T+搜索>>上找一下答案

分享到:

微博关注

bj用友软件

最新信息

U8.51调用WEB失败

U8.51调用WEB失败U8.51调用WEB失败


U8.51-调用WEB失败

自动编号:7498产品版本:U8.51
产品模块:WEB购销存所属行业: 通用
适用产品:U851----WEB关 键 字:WEB
问题名称:调用WEB失败
问题现象:调用WEB失败,无法调用WEB
原因分析:服务器问题
解决方案:由于该单位使用的是静态IP地址分配方式,通过在服务器上运行IPCOMFIG命令找到IP,然后在客户端输入该IP打开WEB即可。

温馨提示:如果您的问题还没有解决,欢迎进入用友云基地

T+普及版可以查询往来双边挂账吗?可以查同单位应收和预收同时挂,往来核销只核应收借贷,不是核销应收和预收,在普及版里边查了要一个一个去对,有可以之前挂了的然后后面核销的吗?普及版好像也支持的吧?

T+普及版可以查询往来双边挂账吗?可以查同单位应收和预收同时挂,往来核销只核应收借贷,不是核销应收和预收,在普及版里边查了要一个一个去对,有可以之前挂了的然后后面核销的吗?普及版好像也支持的吧? T+普及版可以查询往来双边挂账吗?可以查同单位应收和预收同时挂,往来核销只核应收借贷,不是核销应收和预收,在普及版里边查了要一个一个去对,有可以之前挂了的然后后面核销的吗?普及版好像也支持的吧?[]

不能。

热点文章

新闻资讯

  • 【新年首签】天津用友&通广集团签署战略协议

    【新年首签】天津用友&通广集团签署战略协议

    天津用友软件技术有限公司(以下简称天津用友)和天津通信广播集团有限公司(以下简称通广集团)就企业信息化建设事宜进行战略签约。

    参加此次会议有天津用友总经理赵永春,天津用友副总经理王成岩、通广集团副总经理马严、通广集团科技质量部部长尹刚、七一二公司技术质量部部长门国梁、七一二公司技术中心主任黄建尧等。

    image

  • 会计职场堪比宫斗剧

    会计职场堪比宫斗剧

     近几年,各种宫斗剧火爆,《甄嬛传》《芈月传》等等都脍炙人口,许多人经常打趣自己像某个人物,若是在古代能活到第几集。让人不禁想起,会计职场又何尝不是一场宫斗,每天要察言观色,明了领导的内心,就像后宫谁也不敢惹皇后一样。但当你坐上领导位置的时候,盯着你的眼睛就会很多,稍有不慎就会被取代。就像后宫的嫔妃一样,就算坐上了皇后的位置也要时刻担心有没有人觊觎。

    image

知 识 库

  • 用友软件凭证填制环节常见问题及解决方案

    用友软件凭证填制环节常见问题及解决方案

    用友软件凭证填制环节常见问题及解决方案用友软件凭证填制环节常见问题及解决方案

      用友软件的账务处理采用放射式数据处理流程,对业务数据采用集中收集、统一处理、数据共享的操作方法,凭证数据库既是数据归集的“信息仓库”,又是后续业务处理的“信息源泉”。因此,凭证填制数据的正确与否直接关系到后续账表及相关业务信息的准确性。
      在用友软件中,其基础设置及凭证管理模块为我们提供了凭证类别控制、受控科目控制、制单序时控制、支票控制、制单权限控制等功能,加强了对发生业务的及时管理和控制,通过严密的制单控制保证填制凭证的正确性。然而在实际应用中,却常因用户不理解各项控制参数的含义,以及对后续操作的影响;没有准确无误地设置相关控制参数及基础信息;没有正确完整地录入凭证辅助信息等原因,使先进的控制工具无法充分发挥效用,损失了部分数据信息,降低了软件的使用效能。对此,笔者将以用友ERP-U8.72软件为例,总结凭证填制环节的常见问题,结合典型案例,追根寻源,深入剖析其产生的原因,以便对症解决。一、凭证类别设置时常见问题
      出错信息描述:“不满足借方必有条件”,“不满足贷方必有条件”,“不满足借贷必无条件”,“不满足凭证必有条件”。
      典型案例剖析:2009年8月16日,总经理办公室支付业务招待费1 200元,转账支票号ZZR003。凭证内容如下:
      借:管理费用/招待费(660205)1 200
      贷:银行存款/工行存款(100201)1 200
      当凭证保存时,弹出出错信息框,提示“不满足借贷必无条件”。此信息说明用户之前为不同类别的凭证设置了限制条件,指定了相应的限制类型和限制科目。这样,当凭证填制时,系统就会根据所设置的凭证类别判断凭证内容是否符合限制条件,不相符时就会出现类似的出错信息。对于此类问题,用户首先应根据提示信息,认真查对所选凭证类别与所录入的业务内容是否相符,然后进一步判断究竟是凭证类别设置错误,还是会计科目选择错误?
      此案例中的凭证类别选择的是“转账凭证”,转账凭证的限制类型应为“凭证必无”,限制科目为“1001,100201,100202”,即在凭证借贷方不能出现这三个科目。而该凭证的贷方却出现了100201科目,显然违背了所设置的限制条件。进一步判断可知,此问题是因凭证类别设置错误所致的。根据业务内容该凭证类别应为“付款凭证”,而非“转账凭证”。当更正凭证类别后,问题即得到解决。经进一步分析得知,用户在填制凭证时,因为看到在业务中用到了转账支票,就认为这应该是一张转账凭证,从而导致凭证类别判断错误。而追根寻源是由于用户对业务的凭证类别判断不准,不明白凭证类别的限制条件,甚至于不清楚什么是收、付、转凭证。当问题出现时,就会因不理解凭证类别限制条件的含义而找不到问题解决的方向和方法。
      此外,对于此类问题,如果用户在认真查对后,发现凭证类别与凭证内容匹配,但仍出现出错信息,则应考虑可能是因用户粗心将凭证类别的限制条件设置有误。常见的错误有将收款凭证和付款凭证的限制类型设反了,或将转账凭证的限制类型设为“凭证必有”,或未写全限制科目。

  • 浅议电算化会计中若干会计方法

    浅议电算化会计中若干会计方法

    浅议电算化会计中若干会计方法浅议电算化会计中若干会计方法

      一、电算会计中借贷记账法是否不适用
      在借贷记账法中,“借”既可以表示增,也可以表示减,而“贷”既可以表示减,也可以表示增,卢卡?帕乔利提出的复式借贷簿记方法之所以几百年来一直为人们所推崇,正是因为其“有借必有贷,借贷必相等”的锱铢必较、泾渭分明的科学原理。尽管我国会计实务也曾一段时间对增减记账法和收付记账法情有独钟,但最终仍达成共识,采用了国际上通用的借贷记账法。有人以会计软件常以正、负号分别替代借、贷符号为由,企图说服人们相信这一记账法已经难以胜任新形势。应当注意的是,即使借、贷符号在数据库中不采用“借”和“贷”加以表示,也并不表明借贷记账法就可放弃。不可否认,在将借贷记账凭证的发生额登录到总账之后,对于登账后所结计的期末余额往往以正数表示借方余额,而以负数表示贷方余额,甚至在借贷库文件中只设一个金额字段,在该字段中分别以正负号表示借贷方。但所有这些标记都没能改变“有借必有贷,借贷必相等”的规则,其实质仍然是借贷记账法。这里的正、负号与增减记账法的增减符号的属性风马牛不相及。
      从长远来看,随着原始凭证的逐步电子化,记账凭证的自动生成势在必行,届时,何种记账方法使自动生成更可行,当然要根据其科学性而定。智能软件的设计凭借的是科学的方法和严密的思维与推断,而经过了数百年磨练的借贷记账法,无疑是未来智能专家设计会计软件的最佳选择。当然,一味否定增减记账法的科学性也是错误的。在计算机之中,当采用增减记账法填制记账凭证之后,我们完全可以编写一段简短的程序将其转换为借贷记账法下的相应记账凭证。其转换的主要依据是各该科目的记账符号与所属科目类别。以从银行提取现金为例,在增减记账法下,增记“现金”,减记“银行存款”。现金和银行存款都是资产类科目,对资产类科目,其增加就转换为“借”,其减少就转换为“贷”。依此,也可将借贷记账法下的凭证转换为增减法下的凭证。

      二、“反结账、反记账、取消审核”的可行性
      至今,尚有不少会计核算软件设置“取消审核”、“反记账”、“反结账”的功能。在实际工作中,这些设置的确给会计人员的会计处理带来许多方便,尽管许多学者对此提出异议,但不少实务工作者却对其依依不舍。有的学者甚至认为,在计算机特定的工作环境中,反记账的作用不可替代。其理由是,在实际工作中存在大量错误的记账凭证,如果不施行反记账的做法,则将导致账簿中存在大量无用的冗余信息,影响对会计信息的使用。
      所谓电算化会计中“反记账”,事实上也就是将一批原先已经登录到账簿上的发生额从各该账户再予以扣减,使各该账簿恢复至该批凭证登账之前账簿的发生额和余额状态。毋庸置疑,没有人会赞同手工会计下采用“反记账”。对手工的账簿记录,为了保证其有案可稽,当其发生错误时,不准涂改、挖补、刮擦或者用药水消除字迹,不准重新抄写。同时,对两种出错情况的更正应当分别加以严格处理:一是登记账簿时所发生的错误,“应当将错误的文字或者数字划红线注销,但必须使原有字迹仍可辨认”;在实际工作中,由于记账凭证出错而导致账簿记录发生差错时而发生。一般采用两种方式进行相应的修改:一是红字冲销法,二是补充更正法。这些详细而又具体的规定所强调的一点,那就是对出错之处必需留有修改的痕迹。
      在电算会计之中,记账错误和记账凭证填制错误仍然在所难免。虽然红线注销法在电算会计中难以操作,但对出错的电子数据,却不能不留下修改的痕迹。解决的办法只有一个,保留错误电子数据,另作更改的记账凭证,并据以登录账簿,换言之,要将正与误两张凭证同存于会计档案之中,同时,其所登录的正与误两处账簿记录并存于同一账簿之中。《会计核算软件基本功能规范》第十八条也作出与上相同的规定:“发现已经输入并审核通过或者登账的记账凭证有错误的,可以采用红字冲销法或者补充凭证法进行更正;记账凭证输入时,红字可用‘-’号或者其他标记表示”。
      由上可见,不管是手工会计,还是电算化会计,对出错的修改均强调留有痕迹。事实上,电算化会计中,由于电子数据的修改在技术上可不留痕迹,因而更需要对留有痕迹予以强调。

  • 最新文章排行
  • 热门文章排行

管理软件

  • T3卸载就会跳到安装界面去,用360工具也卸载不了。请问这种情况哪位老师遇见过,我们应该如何处理。谢谢、在线等。

    T3卸载就会跳到安装界面去,用360工具也卸载不了。请问这种情况哪位老师遇见过,我们应该如何处理。谢谢、在线等。

    T3卸载就会跳到安装界面去,用360工具也卸载不了。请问这种情况哪位老师遇见过,我们应该如何处理。谢谢、在线等。 T3卸载就会跳到安装界面去,用360工具也卸载不了。请问这种情况哪位老师遇见过,我们应该如何处理。谢谢、在线等。[]

    备份好账套,这种情况只能强制删除了,请备份好账套之后,停止数据库服务和T3产品服务,自动备份服务;然后删除T3安装路径以及C盘下ufcomsql文件夹,然后使用360清除无用注册表,最后重启电脑即可;

  • 用友T3-用友通标准版录完期初后,总账系统和往来管理中往来科目期初余额不一致

    用友T3-用友通标准版录完期初后,总账系统和往来管理中往来科目期初余额不一致

    用友T3-用友通标准版录完期初后,总账系统和往来管理中往来科目期初余额不一致 用友T3-用友通标准版录完期初后,总账系统和往来管理中往来科目期初余额不一致

    用友T3-用友通应收账款在总账系统明细表中期初余额为10元,但在往来管理客户科目余额表中期初余额为110元.
    挂上往来辅助核算之后在总账期初余额里录入期初,后来发现录错了,接着就取消往来辅助核算,直接清空总账期初余额表面的金额(下图红色),却没有删除期初余额往来中的明细(下图蓝色)

关于我们 | 公司动态 | 获奖记录 | 联系我们 | 招聘信息 | 用友产品中心 | 用友云基地
Copyright ©  www.kuaiji66.com  All Rights Reserved 天龙瑞德
京ICP备11046295号-1 技术支持 北京天龙瑞德信息技术有限责任公司   北京海淀上地十街辉煌国际大厦3号楼6层 总机:010-59798025   售后:4009908488
北京天龙瑞德信息技术有限责任公司