Alamofire动态Proxy,报出FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled"

本文探讨了在使用Alamofire网络框架时如何解决动态更换Proxy的问题,通过使用URLSession替代Alamofire的方法实现了动态代理的功能,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Alamofire网络框架时,项目中需要动态替换 Proxy,使用 Alamofire 代码如下:

static var requestManager = Alamofire.SessionManager()
let cfg = Alamofire.SessionManager.default.session.configuration
cfg.connectionProxyDictionary = [
    kCFNetworkProxiesHTTPEnable: true,
    kCFNetworkProxiesHTTPPort: 80,
    kCFNetworkProxiesHTTPProxy: ip
]
requestManager = Alamofire.SessionManager(configuration: cfg)
requestManager.request(...)
复制代码

connectionProxyDictionary中的Proxy,需要是动态的,随时可能变化。但是使用此方法会报出一个错误

FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled"

在使用Alamofire时,官方推荐使用单利来完成初始化,不然就会报出上面的错误。

抱着试试的态度使用系统的URLSession来做这件事,代码如下:

var dataTask: URLSessionDataTask?
//        curl -v "http://xxxxx/uaa/apid/member/code/get" -x "47.91.236.123:80"
        let url = URL(string: "http://xxxxx/uaa/apid/member/code/get")
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        configuration.connectionProxyDictionary = [
            kCFNetworkProxiesHTTPEnable: true,
            kCFNetworkProxiesHTTPPort: 80,
            kCFNetworkProxiesHTTPProxy: "47.91.236.123"
        ]
        let session = URLSession(configuration: configuration)
        dataTask = session.dataTask(with: url!) { (data, response, error) in
            print("----------------------\n")
            if let result = data {
                let str = String(data: result, encoding: String.Encoding.utf8)
                print("result \(String(describing: str))")
            }
            if let msg = error {
                print(msg.localizedDescription)
            }
            print("----------------------\n")
        }
        dataTask?.resume()
复制代码

这样居然可以完成达到这个目的,然后我们就把整个Network层换了。 /(ㄒoㄒ)/~~ 真是个蛋疼的问题!!!!


其实使用Alamofire也可以完成

  1. 需要监听你的Ip变化
  2. 变化了,就重新创建一个Alamofire实例 代码如下:
final class Network {
    static let shared: SessionManager = {
        let configuration = URLSession.default
        cconfiguration.timeoutIntervalForRequest = 30
        configuration.connectionProxyDictionary = [
            kCFNetworkProxiesHTTPEnable: true,
            kCFNetworkProxiesHTTPPort: 80,
            kCFNetworkProxiesHTTPProxy: "47.91.236.123"
        ]
        return SessionManager(configuration: configuration)
    }()
}
复制代码

关于使用动态Proxy在Alamofire的问题

<think>好的,我现在需要帮助用户解决他们遇到的systemctl启动kube-proxy时出现的错误:“kube-proxy.service: main process exited, code=exited, status=200/CHDIR”。用户提到手动启动命令可以工作,但通过systemd服务不行。首先,我要理解这个错误信息的含义。 根据错误信息中的“status=200/CHDIR”,这通常表示进程在启动时无法切换到指定的工作目录。systemd的服务单元文件中有一个`WorkingDirectory`配置项,如果这个目录不存在或服务进程没有权限访问,就会导致这样的错误。接下来,我需要考虑用户可能的配置问题,以及如何引导他们排查。 首先,我应该检查服务文件中的`WorkingDirectory`设置。用户可能没有正确配置这个目录,或者目录的权限不正确。需要让用户确认该目录是否存在,以及服务运行的用户是否有权限访问该目录。此外,如果服务文件中没有显式设置`WorkingDirectory`,默认可能是根目录,但kube-proxy可能需要特定的工作目录,比如存放配置文件或日志的地方。 然后,需要考虑权限问题。服务可能以非root用户运行,比如kube-proxy用户,而该用户可能没有目标目录的读取或执行权限。这时候需要检查目录的所有者和权限设置,并指导用户修改权限或更改服务运行的用户。 另外,SELinux或AppArmor的安全策略也可能导致进程无法切换目录。需要建议用户暂时禁用这些安全模块来测试是否解决问题,如果确实如此,再调整相应的策略。 还有可能服务文件中指定的路径存在拼写错误,或者使用了环境变量,但systemd没有正确解析这些变量。需要用户检查路径是否正确,并确认是否需要在服务文件中显式设置环境变量。 最后,查看日志是定位问题的关键步骤,使用journalctl查看详细的错误信息,帮助进一步确认问题根源。 总结下来,我需要分步骤引导用户检查服务文件的配置、目录存在性和权限、安全策略的影响,以及通过日志获取更多信息。确保用户能够一步步排查,找到具体原因并解决。</think>--- 当 `kube-proxy.service` 报错 `main process exited, code=exited, status=200/CHDIR` 时,表明服务进程在启动时无法切换到指定的工作目录。以下是分步骤排查和解决方案: --- ### **1. 检查服务文件中的工作目录配置** **原因**:服务单元文件(`.service`)中 `WorkingDirectory` 字段指定的目录可能不存在或权限不足。 **操作**: ```bash # 查看服务文件中是否定义了 WorkingDirectory sudo grep "WorkingDirectory" /etc/systemd/system/kube-proxy.service # 示例输出: # WorkingDirectory=/var/lib/kube-proxy ``` **修复**: - 如果目录不存在,手动创建并赋予权限: ```bash sudo mkdir -p /var/lib/kube-proxy sudo chmod 755 /var/lib/kube-proxy ``` - 如果服务文件中未定义 `WorkingDirectory`,添加以下配置(根据实际需求调整路径): ```ini [Service] WorkingDirectory=/var/lib/kube-proxy ``` --- ### **2. 验证目录所有权和权限** **原因**:即使目录存在,若服务运行用户(如 `nobody` 或 `kube-proxy`)无权访问该目录,也会导致 `CHDIR` 失败。 **操作**: ```bash # 检查目录权限和所有者 ls -ld /var/lib/kube-proxy # 示例输出: # drwxr-xr-x 2 root root 4096 Jul 10 10:00 /var/lib/kube-proxy ``` **修复**: - 修改目录所有者(假设服务以用户 `kube-proxy` 运行): ```bash sudo chown kube-proxy:kube-proxy /var/lib/kube-proxy ``` - 放宽权限(临时测试): ```bash sudo chmod 777 /var/lib/kube-proxy ``` --- ### **3. 检查服务运行用户(User/Group)配置** **原因**:服务可能以非特权用户运行(如 `nobody`),导致无法访问受限目录。 **操作**: ```bash # 查看服务文件中的 User/Group 配置 sudo grep "User\|Group" /etc/systemd/system/kube-proxy.service ``` **修复**: - 临时以 `root` 用户运行(测试是否权限问题): ```ini [Service] User=root Group=root ``` - 长期方案:为 `kube-proxy` 创建专用用户并授权目录。 --- ### **4. SELinux/AppArmor 安全策略限制** **原因**:安全模块可能阻止进程切换目录。 **操作**: ```bash # 临时禁用 SELinux(测试用) sudo setenforce 0 # 启动服务观察是否成功 sudo systemctl start kube-proxy # 若成功,恢复 SELinux 并生成策略 sudo setenforce 1 sudo audit2allow -a -M kube-proxy-chdir sudo semodule -i kube-proxy-chdir.pp ``` --- ### **5. 检查服务依赖的文件系统挂载** **原因**:如果 `WorkingDirectory` 位于未挂载的磁盘或临时文件系统(如 `tmpfs`),可能导致目录不可用。 **操作**: ```bash # 确认目录所在文件系统已挂载 df -h /var/lib/kube-proxy # 检查系统启动时是否挂载了所需文件系统 sudo mount -a ``` --- ### **6. 查看详细日志定位问题** **操作**: ```bash # 查看 systemd 日志 sudo journalctl -u kube-proxy -xe # 重点关注以下错误: # - "Failed to change directory" # - "Permission denied" # - "No such file or directory" ``` --- ### **7. 重载服务配置并重启** **操作**: ```bash sudo systemctl daemon-reload sudo systemctl restart kube-proxy ``` --- ### **总结** 1. **目录存在性**:确保 `WorkingDirectory` 路径存在。 2. **权限与所有权**:目录需对服务运行用户开放。 3. **安全策略**:禁用 SELinux/AppArmor 测试,必要时调整策略。 4. **日志分析**:通过 `journalctl` 确认具体错误原因。 通过以上步骤,应能解决因 `CHDIR` 失败导致的 `kube-proxy` 服务启动问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值