尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

XCAP协议详解与OpenXCAP部署运维实战

XCAP协议详解与OpenXCAP部署运维实战 最近帮朋友排查一个语音核心网的小故障现象很典型所有人注册都正常呼叫也能通但软终端上的状态列表全部灰掉联系人不显示在线。SIP抓包看了一圈SUBSCRIBE、NOTIFY都有SBC和AS日志里也找不到有效报错最后问题落在一个平时根本没人关注的组件上——Xcap服务。磁盘满进程还在但所有XCAP文档读出来都是空。这台服务器默默运行了两年多没人给它做过磁盘告警。这次之后我专门把Xcap的部署和使用重新梳理了一遍整理成这篇东西希望对做IMS、RCS、VoIP或者统一通信运维的朋友有帮助。这里先说明一下标题里写的Xcap指的就是XML Configuration Access Protocol行业里习惯把实现该协议的服务端也直接叫做Xcap。它不负责承载媒体面也不参与SIP信令转发但Presence、RCS、策略管理和联系人同步全都依赖它。你如果搭过IMS实验环境或维护过FreeSWITCH、Kamailio附近的Presence业务后面这些内容可以直接照着试。1. 先搞清楚Xcap到底管什么一套藏在SIP背后的“配置数据服务”1.1 XCAP不是什么神秘网关而是HTTP上的XML配置接口XCAP的全称是XML Configuration Access Protocol标准定义在RFC 5875里。你可以把它理解成用HTTP方法PUT、GET、DELETE去读写XML格式的用户配置数据。为什么需要它因为SIP终端和业务服务器之间除了要传呼叫信令、Presence事件还需要同步联系人列表、授权策略这类“配置”。举一个白话场景。办公软终端上的联系人分组、某人能看到谁在线、谁能看我的状态这些信息不能放在终端本地因为终端一换就丢了也不能放在Presence Server内部因为别的网元也想知道。XCAP就是把这些数据集中存起来并提供一个统一接口。SIP终端可以写自己的配置Presence Server、RLS、SCIM这些服务可以按需读取。换句话说XCAP解决的是SIP生态里“用户业务配置怎么写、怎么同步”的问题。用大白话打个比方XCAP像是公司走廊里一块公共白板。HR终端用户负责往白板上贴内容行政部Presence Server、门卫SCIM、项目经理RLS都要看这块白板来决定怎么安排工作。白板本身不负责开会、不负责发布通知但如果白板没了大家就都不知道今天谁值班。1.2 运维中真正会碰到XCAP的五个场景XCAP在日常运维里很少被单独提起但下面几个问题追根溯源基本都会指向它终端联系人列表无法同步软终端配置了“从服务器获取联系人”但分组一直是空的。Presence状态不更新某个人明明在线其他人订阅后看到的却是“离线”或“未知”。授权策略不生效用户设置了“只允许特定分组看我的状态”但实际所有人还是能看到。RLS服务报错Resource List Server需要从XCAP读取“某用户订阅了哪些列表”读不到就导致批量Presence订阅失败。呼叫策略下发异常部分网元通过XCAP动态获取用户的业务属性比如呼叫转移设置读不到就按默认策略处理用户会觉得“功能坏了”。这几个场景都有个共同特点SIP信令本身是通的REGISTER、SUBSCRIBE都能拿到200但业务结果不对。这种“信令通、业务不通”的问题排起来最费劲而XCAP往往是最后一个被想到的。1.3 先建立AUID、XUI和路径的心智模型XCAP排查绕不开三个概念AUID、XUI、文档路径。AUIDApplication Unique ID表示一类XML文档比如resource-lists是联系人资源列表pres-rules是Presence授权规则rls-services是RLS服务配置。XUIXCAP User Identifier表示用户通常就是sip:aliceexample.com这样的URI也有可能是tel:8613800138000这种号码格式。文档路径确定了具体操作哪一份XML文件一般路径形式是/xcap-root/{auid}/users/{xui}/{filename}排障时如果发现404先不要怀疑网络先对着路径看AUID是否写错、XUI里的域名是否小写、文件名是否写成了index.xml而不是index。这类低级错位占了实际排障中很大比例。2. 选型不纠结为什么我选了OpenXCAP这套开源实现2.1 市面上能用的XCAP服务端其实不多XCAP不像Web服务器那样遍地开花做开源的就那么几个。我简单列一下我实际接触过的方案方案类型适用场景备注OpenXCAPJava/Tomcat开源实验环境、中小规模、学习部署简单功能满足标准场景Kamailio xcap_clientC模块非完整服务器配合外部XCAP服务读取列表相当于客户端库不算服务端FreeSWITCH mod_xml_curl集成能力动态读取配置不能独立承担XCAP存储商业SCIM/AS内置设备内置运营商级方案通常跟着IMS全套走单独拆不出来如果你不需要运营商级别的并发和容灾我强烈建议用OpenXCAP。它虽然老但代码量小逻辑简单出错时看日志非常直观。反观商业设备XCAP功能被封装在SCIM里面出了问题你连它的数据库长什么样都看不到排障基本靠提单。2.2 OpenXCAP的组成Tomcat加MySQL再加一个可选LDAPOpenXCAP是Java项目发布时间比较早依赖结构也很传统一个Servlet容器负责接收HTTP请求一个数据库负责存XML文档一套认证模块负责校验用户身份。我实际部署中的推荐组合是JDK 8或11Tomcat 8.5以上9也可以MySQL 5.7或8.0MariaDB我也试过基本兼容OpenLDAP可选如果没有就用数据库里的用户表做认证数据流是这样的客户端软终端、AS、SBC通过HTTP PUT/GET访问Tomcat上的XCAP应用应用解析请求后把XML文档写入MySQL读取时再从MySQL查出来。身份校验在数据库或LDAP里完成。这个架构非常符合“配置数据服务”的定位不涉及媒体流也不会成为SIP链路的一部分。2.3 部署前先画一个拓扑别把服务的边界搞混我见过不少人把XCAP服务部署在信令服务器上和Kamailio塞在一起最终出问题谁也说不清。我的建议是单独一台虚拟机或者容器理由有三个XCAP的HTTP流量虽然不大但日志量和数据库操作会对同机上的SIP转发造成轻微干扰。XCAP服务重启时不能带着SIP核心一起重启分开部署能降低故障半径。排障时需要独立抓包如果混在一台机器上抓包结果会和SIP流量混在一起看半天看不明白。拓扑上我建议XCAP服务器和MySQL分开至少做远程数据库访问认证如果接LDAPLDAP可以放在企业统一认证区。对外只开放一个HTTP/HTTPS端口比如8080或8443数据库端口不要对业务网暴露。3. 一步一步搭出第一个Xcap服务从零到HTTP 2003.1 安装基础依赖JDK、Tomcat、MySQL下面以Ubuntu 22.04为例。命令很常规但几个版本坑我提前说一下。sudo apt update sudo apt install -y openjdk-11-jdk tomcat9 mysql-server sudo systemctl enable --now tomcat9 mysql安装完先确认Java版本和Tomcat版本java -version sudo /usr/share/tomcat9/bin/version.sh这里有一个常见坑Tomcat9默认用Java 11启动如果你环境里装了多个JDK版本Tomcat可能因为找不到JAVA_HOME起不来。建议在/etc/default/tomcat9里显式指定JAVA_HOME/usr/lib/jvm/java-11-openjdk-amd64MySQL初始化完成后创建XCAP专用库和账号sudo mysqlCREATE DATABASE xcap DEFAULT CHARACTER SET utf8; CREATE USER xcap% IDENTIFIED BY C0mplexPass; GRANT ALL PRIVILEGES ON xcap.* TO xcap%; FLUSH PRIVILEGES;提示XCAP里存的都是XML文本字符集必须用utf8或utf8mb4。用过latin1的同事应该都遇到过生僻字联系人存不进去的情况。3.2 部署WAR包与初始化表结构OpenXCAP发布的是一个WAR包可以直接丢到Tomcat的webapps目录下。我把xcap.war放到/var/lib/tomcat9/webapps/Tomcat会自动解压成/var/lib/tomcat9/webapps/xcap/。启动前需要初始化数据库表结构。项目自带的xcap.sql文件通常位于解压目录下的WEB-INF/classes或文档目录里执行导入mysql -uxcap -p xcap /var/lib/tomcat9/webapps/xcap/WEB-INF/classes/xcap.sql导入后可以快速验证一下表是否建好mysql -uxcap -p xcap -e show tables;正常会看到类似users、documents、resource_lists等表。如果一张表都没有大概率是SQL文件路径找错了或者MySQL当前用户名权限不够。3.3 修改配置文件四个关键项决定你能不能用OpenXCAP的配置主要集中在WEB-INF/classes下的几个properties文件里。我总结四个必改项数据库连接串把localhost改成实际MySQL地址注意加useSSLfalse否则MySQL 8会报证书校验错误。数据库账号密码和上面创建的账号保持一致。XCAP根目录标识通常是/xcap/root要和客户端URL前缀一致。认证方式我建议先配成database模式不用一上来就接LDAP等整条链路通了再切。示例片段不同小版本字段命名会有差异关键是找到相应关键字xcap.db.urljdbc:mysql://127.0.0.1:3306/xcap?useSSLfalsecharacterEncodingutf8 xcap.db.userxcap xcap.db.passwordC0mplexPass xcap.root/xcap/root xcap.auth.backenddatabase改完配置记得重启Tomcatsudo systemctl restart tomcat93.4 启动后的健康检查别看到8080端口就以为成功启动后不要急着连业务先做三个验证# 1. 确认Tomcat进程活着 systemctl status tomcat9 # 2. 确认应用端口监听 ss -tlnp | grep 8080 # 3. 访问XCAP根路径 curl -i http://127.0.0.1:8080/xcap/root第三条命令非常关键。如果返回HTTP 200说明应用已经挂上如果出现404多半是WAR包没解压成功看/var/lib/tomcat9/logs/catalina.out有没有异常如果是500一般是数据库连接失败优先检查配置里的账号密码和MySQL的网络权限。我第一次部署时卡在500上很久最后发现是MySQL的bind-address默认绑定127.0.0.1远程连不上。改成0.0.0.0并确认防火墙放行3306后才正常。4. 用curl完成“增删改查”XCAP用户文档的实际操作4.1 第一个PUT创建用户Presence规则装好服务后最直接的验证就是往XCAP里写一份用户文档。以下用curl做一个标准操作把resource-lists文档写到用户alice名下。curl -X PUT \ -u alice:password \ -H Content-Type: application/xcap-elxml \ --data ?xml version1.0 encodingUTF-8? resource-lists xmlnsurn:ietf:params:xml:ns:resource-lists list nameteam entry urisip:bobexample.com/ entry urisip:carolexample.com/ /list /resource-lists \ http://127.0.0.1:8080/xcap/root/resource-lists/users/sip:aliceexample.com/index这里有几个细节值得说明请求头Content-Type必须匹配AUID对应的MIME类型resource-lists对应的是application/xcap-elxml。类型给错了服务端会返回415。-u alice:password是HTTP Basic认证。OpenXCAP默认接受Basic和Digest两种方式但有些终端只支持Digest联调时要先确认。URL里的sip:aliceexample.com必须URL编码吗不必须Tomcat通常能自动处理符号但如果你用的是tel:号码里面的号建议编码成%2B否则容易解析歧义。4.2 GET查询、DELETE删除、版本号处理写成功后用GET验证curl -u alice:password \ http://127.0.0.1:8080/xcap/root/resource-lists/users/sip:aliceexample.com/index返回的应该就是刚才PUT进去的XML原文。服务端还会在响应头里带上Etag这是文档版本号。XCAP协议支持用If-Match、If-None-Match做并发控制。实际场景里两个人同时改同一份文档的情况很多比如用户在用网页改联系人列表同时终端也在同步配置。这时候一定要用Etag控制。流程是先GET拿到Etag再PUT时带上If-Match: 版本号如果服务器上文档已经被别人改了版本号对不上PUT就会失败客户端可以提示“配置冲突请刷新后重试”。删文档就是普通DELETEcurl -X DELETE -u alice:password \ http://127.0.0.1:8080/xcap/root/resource-lists/users/sip:aliceexample.com/index4.3 文档命名空间和MIME type容易错在哪XCAP排障绕不开“命名空间不匹配”这个坑。XML里的xmlns必须与AUID严格对应比如resource-lists的命名空间是urn:ietf:params:xml:ns:resource-listspres-rules是urn:ietf:params:xml:ns:pres-rules。写错一个单词服务端可能拒收或者更坑的是存储成功但读出来的客户端解析不了。另外MIME类型也是重灾区。下面是一张常用的对应表建议收藏AUIDMIME Typeresource-listsapplication/xcap-elxmlrls-servicesapplication/rls-servicesxmlpres-rulesapplication/auth-policyxmlxcap-capsapplication/xcap-capsxml如果客户端总报“格式错误”先抓包看它请求时的Content-Type和XML内容往往一眼就能发现是类型写成了text/xml或者命名空间少了个s。5. 联调最容易翻车的几个点从HTTP 409到4045.1 认证模式Digest、Basic、LDAP三者的取舍XCAP客户端五花八门有的软终端只发Digest有的AS只支持Basic还有的网关会在内部把登录账号映射成SIP URI后再请求XCAP。部署时我建议先用Basic 数据库用户跑通全链路。接口要面向公网或不可信网络时再切到Digest或启用HTTPS。如果企业已有LDAP可以把OpenXCAP的认证切到LDAP后端但注意LDAP返回的用户名和XUI不一定一致需要配映射关系。实际维护中见过一个典型问题在OpenXCAP里配了LDAP后用户用终端同步联系人列表第一次成功、第二次就一直401。后来发现是LDAP账号被锁策略限制连续多次认证失败后会临时锁定。这个不是XCAP的问题但排查时很容易往协议上靠浪费大半天。5.2 URI路径全局目录和用户目录是两套写法XCAP文档分为全局文档和用户文档。全局文档路径长这样/xcap/root/resource-lists/global/index用户文档路径长这样/xcap/root/resource-lists/users/{xui}/index运维配错最多的就是把global和users/{xui}混用。比如管理员想给所有用户下发一个公共联系人列表写成了/users/global/index服务端会认为用户名为global导致配置只对一个人生效。我也见过反向的问题业务网元读取某个用户的列表时用了全局路径最后所有人看到的是同一份联系人列表测试时发现A用户能看见B用户的私人号码这个就是大事故了。所以路径规则一定写进运维手册里。5.3 HTTP错误码对照看到4xx先别慌错误码含义优先排查方向401认证失败账号密码、LDAP锁定、认证模式不匹配403禁止访问用户对全局文档没有写权限或XUI归属不对404文档不存在AUID拼写、XUI大小写、路径global/users写错409冲突XML节点已存在或Etag版本不匹配415不支持的媒体类型Content-Type和AUID不对应500服务器内部错误数据库连接、SQL异常、磁盘满遇到409的时候不要当成“服务器坏了”先查文档是不是已经被写过。XCAP的语义是“如果目标节点不存在则创建重复创建会冲突”这是协议规定不是缺陷。5.4 案例复盘联系人状态列表不显示的一次完整排查顺着一个实际案例把这些点串起来。现场环境是FreeSWITCH集群做语音业务AS节点做Presence终端联系人列表由XCAP下发。用户反馈手机端联系人分组能显示但所有成员在线状态都是灰色的。排查链路先抓SIP终端发起SUBSCRIBEAS返回200 OK信令层面没有异常。再看AS侧日志AS向XCAP服务器请求用户列表时URL是/xcap/root/resource-lists/users/sip:aliceexample.com/index返回404。直接用curl复现这个请求确实404。检查XCAP数据库发现这个目录下只有一个用户sip:aliceexample.com问题出在客户端实际请求时把域名写成了大写SIP:AliceExample.com数据库里以小写存储大小写匹配失败。统一配置项把XUI统一规范成小写后再GET返回200Presence恢复。这个案例看起来低级但在真实环境里非常多。XUI本质上就是字符串按RFC应该不区分大小写但很多实现直接拿字符串做数据库主键导致大小写被区别对待。运维层面能做的最有效动作就是在终端配置文件里统一参数格式并定期巡检XCAP数据库里的用户数据。6. 上线之后的运维“小账本”备份、监控、容灾经验6.1 除了数据库备份配置文件也要留底XCAP的数据核心在MySQL里的documents表这是绝对要备份的。我习惯每天凌晨做一次全量mysqldump保留最近7天每周再导出一份离线归档。mysqldump -uxcap -p xcap /backup/xcap_$(date %F).sql但大部分人只备份了数据库没有备份OpenXCAP的配置文件。部署时用到的xcap.properties、ldap.properties、WAR包版本号建议一起纳入配置管理系统。没有这些文件即使数据库完整换一台机器也起不来服务。6.2 监控指标HTTP状态码比TCP连接数有用得多XCAP是HTTP服务监控指标应该围绕HTTP来定。我在生产环境里主要盯四个4xx比例突然走高大概率是认证配置或路径写错。5xx比例突然走高多半是数据库连接池耗尽或磁盘问题。P95响应时延正常应该在几十毫秒以内如果超过500毫秒先查MySQL慢查询。数据库连接数OpenXCAP是个老项目连接池配置通常不大连接数满了服务直接不可用。另外强烈建议给磁盘空间加一个更激进的告警阈值比如使用率80%就告警不要等到95%。上面提到的磁盘满导致Presence全灰的故障就是被默认的95%告警拖累的等知会到人已经晚了。6.3 高可用和容灾思路无状态应用加有状态数据库OpenXCAP本身几乎是无状态的应用部署两个节点放在负载均衡后面完全可行。请求落到哪个节点都无所谓真正的状态都在MySQL里。所以扩展方案很清晰两个XCAP应用节点外置LB做流量分发。MySQL做主从复制主库故障时手动把VIP切到从库。全局配置不能分片所有用户目录保持单副本逻辑。如果预算允许把XCAP的数据库放到已有的数据库集群里省掉单独维护一套MySQL的工作。6.4 一条私藏经验每周做一次“真实用户演练”最后分享一个我坚持了很久的土办法每周从监控系统里抽一个测试用户用脚本自动完成“PUT一份联系人列表、GET再校验、DELETE清理”三个动作。整个流程30秒但能同时验证数据库读写、认证、路径配置、磁盘、网络五个维度。这套脚本看起来很简单却救过我两次。一次是数据库只读权限被误改服务端一直返回200但根本没写入另一次是负载均衡策略把PUT请求分发到了只读节点测试一跑就暴露了。对比下来比盯着Dashboard的可用率指标可靠得多。Xcap这种服务平时在架构图里经常被画在角落里很容易被忽略但它的状态直接决定Presence、联系人、策略这些用户能感知的功能好不好用。希望这篇梳理能帮你省掉一些排查时间。真正遇到问题的时候记得先看HTTP状态码再查数据库最后才怀疑协议本身顺序对了排障速度能快很多。
返回列表