做集成这行,被问得最多的需求之一就是“文件怎么从对方服务器拿过来”。最近在某个制造企业的数据集成项目里,我接到一个很典型的任务:客户每天早上把当天订单明细上传到外部 SFTP 服务器,我需要用 SAP Cloud Integration 把这个目录里的文件拉进 SAP BTP,再分发给下游系统。实现方式就是入站 SFTP 连接,定时轮询远程目录,把符合规则的文件安全地拉进平台。这个思路听起来简单,但实际配置里藏着不少坑:连接参数填错一个,测试环境通了,生产环境却间歇性失败;私钥格式不对,上线前一夜还在折腾转换。这篇就按我从零搭到上线的完整过程来写,适合正在做 CPI 集成的实施顾问,也适合刚接触 SFTP 接入的初学者。
1. 先把业务场景说清楚:为什么入站文件偏爱 SFTP 轮询
1.1 SFTP 不是唯一选择,却是最省心的选择
做文件集成的时候,对方给你的协议选项通常是四种:FTP、FTPS、SFTP、SCP。很多刚开始接触集成的同事会混淆,尤其是 FTPS 和 SFTP,名字看着像,实际上完全是两套东西。
FTP 基本可以排除。它用明文传用户名和密码,文件内容也是明文,现在稍微正规一点的企业都不接受生产环境用 FTP。即便对方坚持说“我们内部一直这么用”,我也会在方案评审里明确标记风险,建议至少升级到 FTPS。
FTPS 走的是 SSL/TLS 链路,加密逻辑和 HTTPS 类似,在传统制造业、银行外围系统里还有不少存量。它在 SAP Cloud Integration 里能配,但证书体系维护起来比 SFTP 麻烦,尤其是对方证书链不完整的时候,调试成本很高。
SFTP 是跑在 SSH 协议之上的文件传输方式,不是 FTP 的加密版,这点很多人搞混。它默认加密传输,支持密码认证和公钥认证,端口一般走 22。在金融、供应链、政企对接里,SFTP 是当前出现频率最高的文件交换协议。SAP Cloud Integration 对 SFTP 的支持很完整,发送方、接收方都能配。
SCP 常见于 Linux 运维场景,本质上还是基于 SSH 的文件复制,但它缺少交互式的目录列举和操作能力。CPI 的标准适配器里我不会刻意用 SCP,碰到这种需求一般还是让对方改成 SFTP 目录对接。
所以结论很简单:如果外部系统有选择余地,直接推动对方开 SFTP;如果对方只给 FTP,我会在文档里把安全风险写清楚再往下做。
| 协议 | 安全机制 | 文件操作能力 | 生产环境推荐度 |
|---|---|---|---|
| FTP | 明文传输 | 完整 | 不推荐 |
| FTPS | SSL/TLS | 完整 | 看场景可用 |
| SFTP | SSH 加密 | 完整 | 首选 |
| SCP | SSH 加密 | 受限 | 少用 |
1.2 轮询不是退而求其次,是 SFTP 场景下的自然选择
SFTP 协议本身没有“服务器主动推文件给客户端”的机制。服务器就是一个文件仓库,谁能连上来、能读哪些目录,由 SSH 账号权限控制。外部系统把文件放进去之后,它不会通知你说“文件到了”,你必须自己定期去看。
这就是轮询的本质:每隔一段时间,客户端去远程目录扫描一遍,发现匹配规则的新文件就拉下来。你可以类比成每天早上去信箱取报纸,邮局不会打电话叫你,你只需要按固定频率去开信箱就行。
有同事问,为什么不用事件触发。如果对方 SFTP 服务器旁边有一套能发 Webhook 的消息系统,当然可以让它通知 CPI 再去读取,但现实中绝大多数客户没有这种基础能力。就算有,最终“读取文件”这一步仍然需要 SFTP 客户端去执行。轮询绕开了对对方系统额外能力的要求,只要一个 SFTP 账号就能跑通,这是它成为首选的核心原因。
1.3 适合轮询的文件交换场景长什么样
我接触过的典型应用场景包括这几类:银行对账单下载、EDI 报文接收、供应链订单同步、设备日志定期采集、政府平台回执文件拉取。它们的共同点是文件生成时间可预期,不要求秒级实时,通常分钟级到小时级延迟就能满足业务需求。
有一个制造业客户的现场让我印象很深。他们的供应商每天晚上 10 点把发货通知文件传到 SFTP 服务器,第二天早上 6 点生产系统需要拿到数据开始排产。留给 CPI 的处理窗口有 8 个小时,轮询间隔设成 10 分钟,完全跑得过来。这种情况下用实时消息通道反而是过度设计,轮询方案既简单又可靠。
如果你遇到的是高频小文件,比如每隔几秒就来一个,那确实需要重新评估架构。SFTP 轮询在高频场景下对服务器的目录扫描压力不小,文件多了以后,每次轮询都要遍历目录,效率会下降。那种场景更适合队列加文件传输的组合方案,不要硬在 SFTP 轮询上较劲。
2. 动手搭建前,把连接资料和网络条件一次捋清楚
2.1 一份能直接开工的 SFTP 连接资料清单
很多集成项目中途卡住,不是 CPI 配置不会写,而是项目启动时对方只丢过来一句“SFTP 地址我回头给你”,结果一等就是一周。我把每次对接 SFTP 需要的基础信息整理成了清单,让对方按这个清单提供,效率高很多。
清单里最核心的是远程目录路径。很多时候对方给的是incoming/order,但这到底是相对目录还是绝对目录,需要在对接时确认清楚。在 CPI 配置里,路径写错一个层级就会反复报文件不存在。其次是端口,绝大多数 SFTP 服务走 22,但也有客户为了安全改成了非标准端口,比如 2222 或 2200,这个必须问。
用户名和认证方式是第二个关键项。密码认证适合快速联调,但生产环境我强烈建议用私钥认证。如果对方只给了密码,至少确认一下密码策略是否满足企业安全要求。私钥的话,你需要向对方索要 PEM 格式的私钥文件,如果对方只能提供 PuTTY 格式的 PPK 文件,就需要本地做一次格式转换。
| 信息项 | 必须提供 | 备注 |
|---|---|---|
| SFTP 主机地址 | 是 | IP 或域名均可,域名更好维护 |
| SSH 端口 | 是 | 默认 22,确认是否非标准端口 |
| 远程目录 | 是 | 确认是绝对路径还是相对路径 |
| 用户名 | 是 | 专用于集成对接的最小权限账号 |
| 认证方式 | 是 | 密码或私钥,生产优先私钥 |
| Host Key 指纹 | 强烈建议 | 用于连接安全校验,后面会细说 |
| 文件命名规则 | 强烈建议 | 影响轮询的文件匹配条件 |
| 文件处理策略 | 强烈建议 | 读取后删除/归档/保留,影响通道配置 |
2.2 网络白名单和 Cloud Connector:连接超时的头号元凶
SFTP 连接失败有相当高的比例是被网络策略拦了。SAP Cloud Integration 运行在云端,需要主动连接到对方的 SFTP 服务器,这属于出站连接,对方防火墙一般要放行 CPI 出口 IP 段。可现实是,很多企业的安全团队把放行规则卡得很严,只允许个别办公网 IP 访问,连上台式机测试没问题,一到 CPI 就连接超时。
我在项目里通常会让客户先提供一个测试用 SFTP 环境,再用命令行工具做一次基础连通性验证,确认端口能通、用户名密码没问题,再进 CPI 配置。如果对方 SFTP 服务器在客户内网,CPI 默认走公网访问是不行的。SAP 的方案是 Cloud Connector,把这台 SFTP 服务器以 on-premise 的形式暴露出来,CPI 的适配器里把 proxy type 设成 on-premise,才能建立连接。
有一个细节要注意:使用 Cloud Connector 时,SFTP 适配器里填的地址不是原始内网 IP,而是你在 Cloud Connector 里配置的虚拟主机映射。我第一次做内网 SFTP 对接时直接在地址栏写内网 IP,结果怎么都连不通,后来翻文档确认是 proxy type 切换和虚拟地址映射的问题。这个坑值得提前写进方案里。
3. 集成流程搭建全过程:从空白包到可用通道
3.1 创建 Integration Flow 并挂上 SFTP 发送方通道
SAP Cloud Integration 里跑集成的单元叫 Integration Flow,通常简称 iFlow,承载着消息从入站到出站的完整处理链路。入站 SFTP 的第一步,就是建一个包(Integration Package),然后在包里创建一个 iFlow,把 SFTP 适配器作为发送方接入。
打开 Integration Suite 的 Web 界面,进入设计器,新建包后添加 Integration Flow。画布上左侧是发送方,右侧是接收方。从适配器列表里把 SFTP 拖到发送方位置,接下来就会进入通道配置面板。
很多新手容易忽略一个细节:SFTP 发送方通道本身不决定消息的最终去向,它只是定时把文件变成一条消息进入流程。消息进来之后,你可以接 Content Filter、Local Integration Process,或者直接路由到 HTTP、ODATA、其他 SFTP 接收方。这个后续链路的复杂度完全取决于你的业务需求,但入站通道配置的核心目标就是那一句:按什么频率、把哪些文件、用哪种方式拿进 CPI。
创建好 iFlow 之后,先不要急着布署,把发送方参数配置完整再动。因为 SFTP 通道如果连接信息有误,部署后会马上开始反复轮询,错误日志会刷屏,排错反而更难。
3.2 连接和轮询参数逐个拆解,附我常用的取值
SFTP 发送方通道的配置项分布在几个标签页里,不同版本界面的字段名称会有一点差别,但核心参数是稳定的一批。
先看连接的入口参数。地址栏填主机名或 IP,我一般推荐填域名,这样对方以后换 SFTP 服务器 IP 的时候,你只需要改 DNS 解析,不用大动干戈重新部署。端口单独填。认证区域选择密码或私钥方式,输入用户名和密码,或者选择密钥存储里的凭据名称。
处理标签页里是轮询相关配置,这块是重中之重。
轮询间隔(Polling Interval)的单位默认是秒,常见的取值是 30 秒、1 分钟、5 分钟。不是越小越好,间隔太短会增加远程服务器的目录访问压力,也容易在文件还没写完的时候去抢读。间隔太长会让业务数据延迟变大。我一般是根据业务SLA来定:小时级延迟就设 10 分钟,分钟级延迟就设 30 到 60 秒,能覆盖业务要求即可。
文件名模式用通配符。如果你只想要订单文件,对方实际交付的文件名像PO_20250101_001.txt,那么匹配模式填PO_*.txt就行。注意 CPI 里文件名匹配区分大小写,大写的ORDER_*.CSV是匹配不到.csv小写文件的,这个坑我踩过不止一次。
| 参数 | 推荐取值 | 说明 |
|---|---|---|
| 轮询间隔 | 30 到 600 秒 | 按业务时效要求设置 |
| 文件名模式 | 使用通配符 | 如PO_*.txt,区分大小写 |
| 读取模式 | 二进制 Binary | 适合各类型文件 |
| 文件处理 | Read Delete | 确认处理可靠后再启用删除 |
| 归档目录 | 单独建立 | 不要和源目录重叠 |
还有一个容易被忽视的选项是文件完成条件(Completion Condition)。SFTP 轮询执行瞬间,如果对方正在往目录里写文件,文件可能还没写完。CPI 默认行为下,可能读到半个文件。稳妥的做法是让文件方先把文件以临时文件名传上去,传输完成后再改名成正式文件名,这样轮询只抓正式命名的文件。如果对方改不了这个逻辑,就配置完成条件,比如要求文件大小保持稳定,或者指定修改时间超过一定秒数,以此判断文件写完了。
3.3 私有密钥认证:格式、上传和校验
生产环境里我基本都用密钥认证。步骤说复杂也不复杂,但格式坑多。
对方给的私钥通常有两种来源。一种是 Linux 服务器上用ssh-keygen生成的 OpenSSH 格式私钥,文件内容以BEGIN OPENSSH PRIVATE KEY开头,这种一般可以直接用。另一种是 Windows 运维同事用 PuTTYgen 生成的私钥,保存出来是 PPK 格式。CPI 的密钥库不一定直接接受 PPK,需要转换。
PuTTYgen 里转换很简单:打开 PPK 文件,选择 Conversions 菜单里的 Export OpenSSH Key,就会导出 OpenSSH 格式的私钥。如果你手头只有 OpenSSH 私钥但想确认格式,可以用命令查看文件头部,再配合ssh-keygen做格式精化:
# 查看私钥文件头部格式 head -1 id_rsa # 转换成严格的 PEM 编码格式 ssh-keygen -p -f id_rsa -m PEM转换完成后,把私钥内容上传到 Cloud Integration 的 Security Material 里,类型选 Private Key,上传私钥文件,同时可以配置一个关联的用户名。然后回到 SFTP 适配器的认证区域,选择刚才创建的凭据。
这里有个经验要分享:私钥文件如果带了 passphrase,部署后每次轮询都需要正确解密。很多人把 passphrase 填错,结果通道状态一直显示认证失败。排查时建议先用本地工具验证私钥能不能正常登录目标 SFTP,确认密钥本身没问题,再怀疑 CPI 配置问题。
另外,Host Key 验证我建议显式开启。CPI 首次连接时会缓存远程服务器的指纹,如果对方服务器指纹发生变化,通道会中断。表面上这是增加了维护成本,实际上这是防止中间人攻击的重要手段。可以通过ssh-keyscan获取对方的 Host Key:
ssh-keyscan -p 22 sftp.example.com拿到的指纹添加进 CPI 安全配置后,每次连接都会做校验,心里踏实很多。
4. 文件拉进 BTP 之后:防重、容错和归档策略
4.1 轮询模式的“锁”,不是你以为的那种数据库锁
CPI 的 SFTP 轮询模式有一个内置的防止重复读取机制:某个文件被某次轮询选中后,会进入处理状态,在文件被处理完或者超时之前,后续轮询不会再抓它。这和数据库行锁不是一回事,你可以理解成 CPI 在内存和持久化存储里记录了“这个文件我已经拿走了”。
这个机制在单节点部署下表现很好。但如果是多 worker 节点扩展的租户,多个节点同时轮询同一个目录,理论上可能会产生并发读取同一文件的情况。SAP 的适配器做了分布式锁,但我在实际项目里遇到过极端情况下文件重复处理的现象。安全起见,我通常给 iFlow 加上幂等逻辑:在文件内容或者业务主键层面,通过 Data Store 记录已处理过的文件清单,后续消息进来先做查重。基础设施的锁解决不了业务层面的重复,业务逻辑的幂等才是最终防线。
文件读完之后怎么处理,是在适配器的处理方式里选的。有直接在读取后删除的 Read Delete 模式,也有归档移动的模式。我建议新项目上线初期先不要启用删除,让对方文件保留在远程目录里,你只读不删,观察一周确认处理链路稳定,再切换成自动删除。万一流程后期改逻辑,历史文件还能重新拉一次。
4.2 处理失败之后,文件去哪里了
SFTP 通道读取文件后生成了消息,消息进入集成流程。如果流程后面的处理环节报错,消息会进入 CPI 的错误队列开始重试。这里很多人容易误解:文件已经从远程目录“读过”了,但未必代表它被成功处理完。
如果配了 Read Delete 模式,SFTP 服务器上的文件已经删除,消息处理失败重试时只能依赖 CPI 内部的持久化消息,这依赖系统的可靠存储,通常没问题,但业务上会要求“原始文件必须有据可查”。如果配的是保留文件模式,消息处理失败后,文件还在远程目录里,但要注意它会不会被下一次轮询重新读到。CPI 的处理状态会阻止它被立刻重新读取,可如果消息已经过期,或者通道被重新部署,状态被重置,文件就可能被再拉一次。
我的处理建议是:在 iFlow 里加全局异常分支,记录失败消息的文件名和失败原因到 Data Store,同时发告警通知。然后人工决定是重新推送文件到目录,还是手动触发流程重放。生产环境里“自动全搞定”的想法很危险,文件集成的核心诉求是可靠的最终一致。
4.3 远程文件归档:别让源目录变成垃圾场
有些外部系统比较原始,文件传上去之后就什么都不管,远程目录越积越多。轮询每次都要扫描整个目录,文件一多,目录列举耗时变长,匹配也会变慢。这时候归档策略就很重要。
一个常见做法是在 CPI 适配器里配置归档目录,文件读取成功后通过 Move 操作移动到指定归档位置。我在配置时会给归档目录定绝对路径,比如/archive/orders/,并且确保这个归档目录不在轮询的匹配范围内,否则会形成循环:文件被移动到归档目录后,如果轮询目录配置过宽,它可能又被当成新文件再读一次。
对方如果愿意配合,更好的方式是让他们自己执行归档策略:文件生成后保留 7 天或 30 天,超期自动清理。作为集成实施方,我会在接口文档里写清楚建议的保留周期,让客户运维去配置计划任务。集成环节只负责把文件安全地拿下来并做后续处理,不该越俎代庖去管对方服务器的存储清理。
5. 常见问题排查与避坑实录
5.1 连接超时和认证失败:先查链路再查配置
入站 SFTP 第一个常遇问题就是连接超时。错误日志里出现Connection timed out,九成是网络不通或者防火墙策略没放行。我先在本地用命令验证,再用 CPI 通道做真实连接,两步一对比,问题在哪里一目了然。
# 测试端口是否可达 nc -zv sftp.example.com 22 # 用 sftp 命令验证认证信息 sftp -P 22 user@sftp.example.com如果主机名解析有问题,也容易误报成连接超时。我在一次联调中遇到对方给了内网域名,本地能通,但 CPI 在公网环境根本无法解析这个 DNS,最后让对方改成公网映射域名才解决。
认证失败报错时,先确认用户名密码没问题,再确认密钥格式和凭据选择。有个容易漏的点:如果 SFTP 服务器限制了登录来源 IP,CPI 出口 IP 不在白名单里,就会表现为“认证成功但是权限拒绝”之类的高级错误日志。这种要拿着 CPI 的出口 IP 段去和安全团队核对,跟纯配置问题区分开。
5.2 Host Key 变化和证书校验:宁可维护成本高一点
连接拿到Host key verification failed是非常典型的报错。最常见的触发场景是对方换了 SFTP 服务器,或者服务器重建后指纹变了。另一个场景是首次连接时没把 Host Key 存进 CPI,连接被拒绝。
我见过有些方案会建议关闭 Host Key 校验来临时绕过问题,这在测试环境里图省事可以接受,生产环境我坚决不这么干。SFTP 连接本身就是加密的,如果 Host Key 校验关闭,客户端对服务器身份不设防,中间人攻击一旦发生,传输的文件内容就有被篡改的风险。建立标准流程,每次服务器变更就让对方提供最新指纹,更新到 CPI 安全配置里,维护成本并没有想象中高。
5.3 文件名匹配和轮询时间的暗坑
大小写问题前面提过,再补一个容易被坑的点:模式匹配的适用范围。假如远程目录下有PO_20250101.csv和PO_SUMMARY.csv,你填PO_*.csv,两个都会被拉下来。如果你只需要每日明细文件,就要用PO_[0-9]*.csv这样的精确模式,把汇总文件排除掉。多花一分钟把匹配规则定义清楚,能省掉下游数据过滤的一堆麻烦。
轮询时间的暗坑是文件写入未完成。外部系统如果是个老旧的批量脚本,先直接往目标目录写正式文件,再慢慢往文件里追加内容,CPI 恰好在这个时间窗口扫描到,拉到一半文件就处理了。这种情况下,任何配置层面的轮询间隔调整都治标不治本,必须推动对方改成“临时文件加改名”的交付方式,或者你配置完成条件去兜底。我在需求评审阶段就会把这个规则明确写进接口规范,能避免上线后一堆脏数据入库。
5.4 大文件轮询超时和消息积压
单个文件上百兆的场景,轮询拉取和后续处理都会超过默认超时。现象是消息在队列里反复重试,或者 iFlow 处理时间超过通道超时阈值直接报错。
处理思路是分级优化。如果文件是文本格式,可以考虑在 CPI 里做流式读取,避免一次性加载到内存。如果文件是压缩包,可以开启 ZIP 解压处理,拆成多个小消息。如果业务允许,更推荐让对方按业务维度拆分成多个小文件,毕竟 SFTP 本身就不是为超大文件传输设计的。
我在一个设备日志项目里,对方每次都传 500MB 以上的 CSV,用默认配置几乎必挂。后来推动对方按小时分文件,单文件控制在 50MB 以内,再加上轮询间隔拉长,问题彻底解决。遇到大文件,先改拆分策略,再调参数,顺序不要搞反。
做完整套入站 SFTP 的对接,我最深的体会是:文件集成项目里,真正的功夫往往不在 CPI 页面的那些按钮上,而在前期的网络验证、文件命名规则约定、认证方式选型这些看起来不起眼的环节。你把对方的技术能力和使用习惯摸清楚,把接口规范写严谨,后面配置 SFTP 通道就是水到渠成的事情。特别是成功文档里约定好“对方必须用临时文件名传输再改名”这一条,能帮你挡住至少一半的脏数据问题。初次对接时,也建议所有配置先在测试目录上跑通一轮,确认读取、处理、归档的逻辑全部符合预期后,再向生产环境切换,整个过程会从容很多。