本文的目的是介绍redis报protocolerror的真正原凶的详细情况,特别关注redisprotobuf的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解redi
本文的目的是介绍redis 报 protocol error 的真正原凶的详细情况,特别关注redis protobuf的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解redis 报 protocol error 的真正原凶的机会,同时也不会遗漏关于ChromeDriver ERR_SSL_PROTOCOL_ERROR尽管--ignore-certificate-errors、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveRequestProto的实例源码、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveResponseProto的实例源码、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetCurrentEditLogTxidRequestProto的实例源码的知识。
本文目录一览:- redis 报 protocol error 的真正原凶(redis protobuf)
- ChromeDriver ERR_SSL_PROTOCOL_ERROR尽管--ignore-certificate-errors
- org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveRequestProto的实例源码
- org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveResponseProto的实例源码
- org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetCurrentEditLogTxidRequestProto的实例源码
redis 报 protocol error 的真正原凶(redis protobuf)
前段时间写了个文章详细描述了在什么场景下会出现 redis 的 protocol error 错误,但是手抽筋, 不小心点错给删了,而且还原不了,没办法了,只能重写一下,但是没上次那么详细了,如果不太明白就看源代码吧!首先呢,这种错误是基于使用了 phpredis 的的长连接和 multi 功能才会出现!这里有两个问题
1、当你开了事务,做了 N 次写操作,然后又 discard 之后又做了 M 次操作 (M 小于 N),这样请求就会被阻塞住 (这个操作无论使用短连接还是长连接,都能复现),具体看代码:
$redis = new Redis();
$redis->connect(''localhost'', 6379);
$redis->multi();
$redis->set(''test'', 10);
$redis->zIncrBy(''test2'', 1, ''bbb'');
$redis->discard();
$redis->multi();
$redis->zIncrBy(''test2'', 2, ''bbb'');
$redis->exec();//操作会阻塞在这里
因为 phpredis 在 discard 成功后,没有清理 callback list,所以卡住了。
2、开事务,做 N 次操作,discard 之后再做 M 次操作 (但这里 M 大于 N),多刷几次就会出现 protocol error (这个必须使用长连接才会复现)!
$redis = new Redis();
$redis->pconnect(''localhost'', 6379);
$redis->multi();
$redis->set(''test'', 10);
$redis->discard();
$redis->multi();
$redis->zIncrBy(''test2'', 2, ''bbb'');
$redis->zIncrBy(''test2'', 1, ''bbb'');
$redis->exec();
跟上面原因一样,discard 没的清理 callback list, 就会出现 stream 里面的数据没读完!协议就完全乱掉了,
那么上面说的 callback list 又是什么东西呢?在 redis 里面,当你使用了 multi,在执行 exec 之前的请求基本都是返回 + QUEUED(如果需要了解更详细 redis 协议,请见 redis.io),而真正返回数据是等 exec 执行之后,才去解析返回数据。所以 phpredis 针对不同的请求处理方式是不一样的,所以在开启了 multi 之后,phpredis 会维护一个处理函数列表,比如 set (k,v) 这需要绑定一个 bool 值处理函数,而 zincrBy 需要绑定一个 double 值处理函数,执行 exec 之后,去遍历这个列表处理返回数据就即可。
由于 redis 针对 multi 之后的请求都是队列并没有执行,所以客户端可以使用 discard 命令来清空这个队列,同时客户端也应该将之前绑定的函数列表一并清除,可是 phpredis 对于 discard 的处理仅仅是发送了 discard 命令到 redis 服务端,却没有清空处理函数列表。只是在下一次执行 multi 的时候,他仅仅是将这个处理函数列表中一个叫 current 的指针值为 NULL (这个列表是一个单向连表,head 表示头元素,current 表示尾元素),可是他忽略了 head, 因为函数列表一旦进入处理是从 head 开始,只有需要新加函数到列表的时候才会用到 current。所以在 phpredis 里面,执行一条命令,再 discard, 再执行两条命令之后,这个处理函数列表里只有一个函数 (正确应该是两个,而且还是最开始加的那一个,后面加的两个,不翼而飞了。。),处理函数与返回数据不配对,协议自然也就乱了,这就是 protocol error 报错的由来....
本想着提个 bug 给 phpredis 就好了,结果提了也不见他们修改,于是就自己改了,修改的地方:
https://github.com/scgywx/phpredis/commit/3f05eb7acd3b7f64d1f4f857767b5dd74d585cd9
ChromeDriver ERR_SSL_PROTOCOL_ERROR尽管--ignore-certificate-errors
我正在尝试使用带有硒和ChromeDriver的本地主机(没有HTTPS)上的集成测试。
Chrome需要使用https证书,但是根据[这个](http://codingdict.com/questions/61436问题,我知道我可以使用arg来绕过它--ignore-certificate-errors
我还增加了自己的功能acceptInsecureCerts
,因为这似乎是适当的做法(docs)
chromedriver的响应仍然不是我所期望的:
该网站无法提供安全的连接应用,但发送的响应无效。ERR_SSL_PROTOCOL_ERROR
我的代码如下:
from selenium import webdriverfrom selenium.webdriver.chrome.options import Options# make options (principally to ignore certificate)options = webdriver.ChromeOptions()options.add_argument(''--ignore-certificate-errors'')# add acceptInsecureCertscapabilities = options.to_capabilities()capabilities[''acceptInsecureCerts''] = Trueprint(capabilities) # see belowdriver = webdriver.Remote( command_executor=SELENIUM_HUB, desired_capabilities=capabilities)print(driver.__dict__) # see further belowapp_login_url = ''http://app:8000/accounts/login/''driver.get(app_login_url)
我的能力:
{''acceptInsecureCerts'': True,''browserName'': ''chrome'',''goog:chromeOptions'': {''args'': [''--ignore-certificate-errors''], ''extensions'': []},''platform'': ''ANY'',''version'': ''''}
这是我的驱动程序信息,似乎只acceptInsecureCerts
考虑了arg:
{''_file_detector'': <selenium.webdriver.remote.file_detector.LocalFileDetector object at 0x7fb42bde10f0>,''_is_remote'': True,''_mobile'': <selenium.webdriver.remote.mobile.Mobile object at 0x7fb42bb5e400>,''_switch_to'': <selenium.webdriver.remote.switch_to.SwitchTo object at 0x7fb42bdd4898>,''capabilities'': {''acceptInsecureCerts'': True, ''acceptSslCerts'': True, ''applicationCacheEnabled'': False, ''browserConnectionEnabled'': False, ''browserName'': ''chrome'', ''chrome'': {''chromedriverVersion'': ''74.0.3729.6 '' ''(255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29})'', ''userDataDir'': ''/tmp/.com.google.Chrome.vc1ZvB''}, ''cssSelectorsEnabled'': True, ''databaseEnabled'': False, ''goog:chromeOptions'': {''debuggerAddress'': ''localhost:40815''}, ''handlesAlerts'': True, ''hasTouchScreen'': False, ''javascriptEnabled'': True, ''locationContextEnabled'': True, ''mobileEmulationEnabled'': False, ''nativeEvents'': True, ''networkConnectionEnabled'': False, ''pageLoadStrategy'': ''normal'', ''platform'': ''Linux'', ''proxy'': {}, ''rotatable'': False, ''setWindowRect'': True, ''strictFileInteractability'': False, ''takesHeapSnapshot'': True, ''takesScreenshot'': True, ''timeouts'': {''implicit'': 0, ''pageLoad'': 300000, ''script'': 30000}, ''unexpectedAlertBehaviour'': ''ignore'', ''version'': ''74.0.3729.169'', ''webStorageEnabled'': True, ''webdriver.remote.sessionid'': ''1cf77f237e966bac6ca15d4d9c107423''},''command_executor'': <selenium.webdriver.remote.remote_connection.RemoteConnection object at 0x7fb42be0cf98>,''error_handler'': <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7fb427d08a20>,''session_id'': ''1cf77f237e966bac6ca15d4d9c107423'',''w3c'': False}
为什么我仍然看到ERR_SSL_PROTOCOL_ERROR
?
答案1
小编典典此错误消息…
This site can’t provide a secure connection app sent an invalid response. ERR_SSL_PROTOCOL_ERROR
…表示 ChromeDriver 无法启动/产生新的 WebBrowser, 即本地主机上的 Chrome浏览器 会话。
正如你所看到的这个问题,你对 本地主机(没有HTTPS)
按照此评论一眼罩的解决办法是增加argument
--allow-insecure-localhost
通过chromeOptions()
如下:
''goog:chromeOptions'': {''args'': [''--allow-insecure-localhost''], ''extensions'': []}
但是你的主要问题似乎是与 能力 ,你必须设置platform
为集合S ANY
如下:
{''acceptInsecureCerts'': True,''browserName'': ''chrome'',''goog:chromeOptions'': {''args'': [''--ignore-certificate-errors''], ''extensions'': []},''platform'': ''ANY'',''version'': ''''}
正如WebDriver-W3C Living Document的 platformName
部分提到的那样,以下平台名称通常具有易于理解的语义,并且在匹配功能时,可以通过将其作为已知操作系统的有效同义词来实现最大的互操作性:
Key System--- ------"linux" Any server or desktop system based upon the Linux kernel."mac" Any version of Apple’s macOS."windows" Any version of Microsoft Windows, including desktop and mobile versions.
注意 :此列表并不详尽。
从New Session返回功能时,返回更特定的platformName是有效的,从而允许用户正确标识WebDriver实现在其上运行的操作系统。
因此"platform":"ANY"
, 与其 传递 期望的功能 对象, 不如说 是更具体的"platform":"linux"
方法。
您可以在带有参数的http POST到/
session的Curl错误中找到相关的讨论:{“ desiredCapabilities”:{“
browserName”:“ chrome”,“ platform”:“
ANY”与Selenium和PHPUnit
有关 ChromeDriver , Chrome 和 Selenium Client 版本的更多信息将有助于我们以更好的方式分析问题。但是,根据
ChromeDriver的 历史记录,最近几个版本的 ChromeDriver 中解决了与 证书错误 处理相关的以下问题: __
- 允许通过DevTools处理证书错误:由于无头chrome无法显示SSL证书错误的UI警告,因此发布了一个修复程序以将错误暴露为DevTools事件,并控制通过DevTools命令执行的操作。
- 提供无头处理Chromedriver / Selenium中的证书错误的功能:以前,通过用户界面版本的Chromium(如)中的CLI开关控制的某些与安全相关的选项被
--ignore-certificate-errors
忽略,只能通过devtools进行设置。因此,有必要certificateError
在以浏览器为目标的DevTools客户端上覆盖和处理事件。一个补丁发布实施新DevTools方法的使用,以替代证书错误处理浏览器的宽这使得在无头模式忽略证书错误太多。 - 通过DevTools进行全局证书错误处理:以前,DevTools允许处理单个目标/ WebContents的证书错误,但是当创建新目标(例如,单击target = _blank链接)时,通常无法足够快地发送
Security.enable
/Security.setOverrideCertificateErrors
命令在尝试导航之前。一个修复用简单的“忽略所有证书错误”模式发布,取而代之的是新的,而不是过时的旧覆盖命令setIgnoreCertificateErrors
命令,它也暴露了在浏览器上的目标的安全域,以促进全球范围内应用该重写了整个浏览器。
结论
- 确保添加了以下参数/功能:
--allow-insecure-localhost
acceptInsecureCerts
--ignore-certificate-errors
- 使用时
''chromedriverVersion'': ''74.0.3729.6''
,请确保您也正在使用''chrome'': ''74.0''
(根据ChromeDriver v74.0.3729.6发行说明) - 确保您使用的是最新发布的 Selenium v3.141.59 客户端。
org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveRequestProto的实例源码
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,AddCacheDirectiveRequestProto request) throws ServiceException { try { long id = server.addCacheDirective( PBHelper.convert(request.getInfo()),PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,EnumSet<CacheFlag> flags) throws IOException { try { AddCacheDirectiveRequestProto.Builder builder = AddCacheDirectiveRequestProto.newBuilder(). setInfo(PBHelper.convert(directive)); if (!flags.isEmpty()) { builder.setCacheFlags(PBHelper.convertCacheFlags(flags)); } return rpcProxy.addCacheDirective(null,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,EnumSet<CacheFlag> flags) throws IOException { try { AddCacheDirectiveRequestProto.Builder builder = AddCacheDirectiveRequestProto.newBuilder(). setInfo(PBHelperClient.convert(directive)); if (!flags.isEmpty()) { builder.setCacheFlags(PBHelperClient.convertCacheFlags(flags)); } return rpcProxy.addCacheDirective(null,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,AddCacheDirectiveRequestProto request) throws ServiceException { try { long id = server.addCacheDirective( PBHelperClient.convert(request.getInfo()),PBHelperClient.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public long addCacheDirective(CacheDirectiveInfo directive,builder.build()).getId(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveResponseProto的实例源码
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,AddCacheDirectiveRequestProto request) throws ServiceException { try { long id = server.addCacheDirective( PBHelper.convert(request.getInfo()),PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,AddCacheDirectiveRequestProto request) throws ServiceException { try { long id = server.addCacheDirective( PBHelperClient.convert(request.getInfo()),PBHelperClient.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public AddCacheDirectiveResponseProto addCacheDirective( RpcController controller,PBHelper.convertCacheFlags(request.getCacheFlags())); return AddCacheDirectiveResponseProto.newBuilder(). setId(id).build(); } catch (IOException e) { throw new ServiceException(e); } }
org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetCurrentEditLogTxidRequestProto的实例源码
public GetCurrentEditLogTxidResponseProto getCurrentEditLogTxid(RpcController controller,GetCurrentEditLogTxidRequestProto req) throws ServiceException { try { return GetCurrentEditLogTxidResponseProto.newBuilder().setTxid( server.getCurrentEditLogTxid()).build(); } catch (IOException e) { throw new ServiceException(e); } }
public long getCurrentEditLogTxid() throws IOException { GetCurrentEditLogTxidRequestProto req = GetCurrentEditLogTxidRequestProto .getDefaultInstance(); try { return rpcProxy.getCurrentEditLogTxid(null,req).getTxid(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
public long getCurrentEditLogTxid() throws IOException { GetCurrentEditLogTxidRequestProto req = GetCurrentEditLogTxidRequestProto .getDefaultInstance(); try { return rpcProxy.getCurrentEditLogTxid(null,req).getTxid(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
public GetCurrentEditLogTxidResponseProto getCurrentEditLogTxid(RpcController controller,GetCurrentEditLogTxidRequestProto req) throws ServiceException { try { return GetCurrentEditLogTxidResponseProto.newBuilder().setTxid( server.getCurrentEditLogTxid()).build(); } catch (IOException e) { throw new ServiceException(e); } }
public GetCurrentEditLogTxidResponseProto getCurrentEditLogTxid(RpcController controller,GetCurrentEditLogTxidRequestProto req) throws ServiceException { try { return GetCurrentEditLogTxidResponseProto.newBuilder().setTxid( server.getCurrentEditLogTxid()).build(); } catch (IOException e) { throw new ServiceException(e); } }
public long getCurrentEditLogTxid() throws IOException { GetCurrentEditLogTxidRequestProto req = GetCurrentEditLogTxidRequestProto .getDefaultInstance(); try { return rpcProxy.getCurrentEditLogTxid(null,req).getTxid(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
public GetCurrentEditLogTxidResponseProto getCurrentEditLogTxid(RpcController controller,GetCurrentEditLogTxidRequestProto req) throws ServiceException { try { return GetCurrentEditLogTxidResponseProto.newBuilder().setTxid( server.getCurrentEditLogTxid()).build(); } catch (IOException e) { throw new ServiceException(e); } }
public long getCurrentEditLogTxid() throws IOException { GetCurrentEditLogTxidRequestProto req = GetCurrentEditLogTxidRequestProto .getDefaultInstance(); try { return rpcProxy.getCurrentEditLogTxid(null,req).getTxid(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
public GetCurrentEditLogTxidResponseProto getCurrentEditLogTxid(RpcController controller,GetCurrentEditLogTxidRequestProto req) throws ServiceException { try { return GetCurrentEditLogTxidResponseProto.newBuilder().setTxid( server.getCurrentEditLogTxid()).build(); } catch (IOException e) { throw new ServiceException(e); } }
public long getCurrentEditLogTxid() throws IOException { GetCurrentEditLogTxidRequestProto req = GetCurrentEditLogTxidRequestProto .getDefaultInstance(); try { return rpcProxy.getCurrentEditLogTxid(null,req).getTxid(); } catch (ServiceException e) { throw Protobufhelper.getremoteexception(e); } }
今天关于redis 报 protocol error 的真正原凶和redis protobuf的介绍到此结束,谢谢您的阅读,有关ChromeDriver ERR_SSL_PROTOCOL_ERROR尽管--ignore-certificate-errors、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveRequestProto的实例源码、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.AddCacheDirectiveResponseProto的实例源码、org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetCurrentEditLogTxidRequestProto的实例源码等更多相关知识的信息可以在本站进行查询。
本文标签: