我的应用程序与许多其他基于 HTTPS 的服务交互。由于我们使用它们的频率很高,我担心使用 HTTPS 对性能的影响。
是否有任何机制(时间限制或任何其他永久性)可用于防止 HTTPS 握手和其他潜在瓶颈?
当然,我不想使用 HTTP :)
我的应用程序与许多其他基于 HTTPS 的服务交互。由于我们使用它们的频率很高,我担心使用 HTTPS 对性能的影响。
是否有任何机制(时间限制或任何其他永久性)可用于防止 HTTPS 握手和其他潜在瓶颈?
当然,我不想使用 HTTP :)
在 SSL 中有连接,也有会话。
连接以握手开始,并在任何一方通过发送警报消息声明它时结束close_notify
。典型的 Web 浏览器和服务器会在一段时间内保持连接打开,一两分钟不活动后关闭它们;通过该连接发送一个或多个 HTTP 请求和响应。在正常的 HTTPS 上下文中,SSL 连接和底层 TCP 连接之间存在一对一的映射:对于每个 TCP 连接(到端口 443),都会有一个 SSL 连接,当 SSL 连接结束时,底层 TCP 连接已关闭。
会话涉及在“完全握手”中发生的非对称加密。在连接开始时发生的握手过程是关于建立将用于保护该连接的数据的加密算法和密钥。握手有两种:
完全握手是客户端和服务器在彼此不认识时所做的事情(他们以前没有交谈过,或者那是很久以前的事了)。在完整的握手中,证书被发送,并且非对称加密(RSA、Diffie-Hellman...)发生。
缩写握手是客户端和服务器相互记住的内容;更准确地说,他们记住了他们在之前的完整握手中建立的算法和密钥,并同意重用它们(从技术上讲,他们重用“主密钥”并从中派生新的加密密钥用于此连接)。
具有完整握手的连接,以及重用该完整握手的具有缩写握手的连接集一起构成会话。
缩写握手比完整握手更有效,因为它意味着更少的网络往返,更小的握手消息,并且根本没有非对称加密。
对于性能,总的来说,您需要以下内容:
尽可能保持连接打开。“打开的连接”使用一些内存资源(双方必须记住密钥)和系统资源(用于底层 TCP 连接,保持打开状态)。但是,保持连接活动不涉及网络流量,可能除了可选的“ TCP keepalive ”。
当连接不能保持打开时(例如释放系统资源),最好让客户端和服务器记住会话,以便在重新连接时可以进行简短的握手。Web 服务器有各种默认和可配置的策略。例如,Apache (with ) 使用一个为size和durationmod_ssl
定义的缓存;服务器“忘记”一个会话,当它的缓存已满并且需要一些额外的空间时,或者当达到超时时,以先发生的情况为准。
如果您可以控制服务器的配置,那么您可能希望增加连接终止的“非活动超时”,并增加会话缓存大小和持续时间。如果您无法控制服务器,那么您的问题就没有实际意义:无论您做什么,它都必须与服务器提供的兼容。您可以以某种方式强制服务器不要忘记会话,方法是定期打开一个带有简短握手的新连接,但这不一定是一个好主意(通常,当服务器忘记会话时,这或多或少是有充分理由的)。
无论如何,你要采取措施。这是一个关于性能的问题;抽象的推理不能给出明确的答案。通常的经验法则是,性能问题直到在现实生活中被适当地测量,或者至少在具有合理代表性的原型系统中才存在。
无论如何,很难以较小的成本获得与 SSL 相同的安全功能。在不以某种方式牺牲安全性的情况下,用“自定义”替换 SSL 不太可能在性能方面提供很大的改进。
有关 SSL 的演练,请参阅此答案。了解 SSL 内部结构确实有助于思考任何涉及 SSL 的设计。
这应该是一个评论,因为您的问题中没有足够的信息来诊断问题/提出明确的答案,但它有点长......
从您的问题中很难判断您的应用程序是什么样的。您是指在您的服务器上运行的代码,它使 HTTPS 调用其他服务,还是从浏览器进行调用?对少量服务器的调用是可预测的吗?
如果 HTTPS 调用的客户端是您的应用程序代码,那么您将从利用 keepalive(如果 HTTPS 服务器支持)中获得巨大好处。根据您的应用程序的工作方式,这可能意味着管理一个连接池(这可能很棘手),但是一些反向代理将支持这一点。
也许您只需要使用 HTTPS 服务已经提供的缓存信息 - 通过本地缓存代理路由请求会有所帮助。
或者,如果您控制远程服务,则使用 VPN 而不是 TLS 将消除握手开销(大部分时间)。
如果收敛是在客户端,那么它就变成了一个非常不同的问题。如果多个请求全部/大部分都发送给您的服务器,那么解决方案可能是启用(分布式)ssl 会话缓存。当然你应该启用keepalive(我知道Ralph Engeschall 说你不应该对mod_ssl 和MSIE 执行此操作——但那是很久以前的事了——因为MSIE7 的大多数问题都已修复)。