首页 文章 精选 留言 我的

精选列表

搜索[Bug修复],共10000篇文章
优秀的个人博客,低调大师

Elasticsearch集群UNASSIGNED shareds问题 修复

线上有3台es组成集群,其他有两台非正常关机了,早上过来发现集群状态为红色,提示"24 UNASSIGNED shareds": 1)查看集群相关信息: curl'localhost:9200/_nodes/process?pretty' 记下这个node的id号; 2)然后找出UNASSIGNED 的相关信息,方便后续修改! # curl -XGET http://localhost:9200/_cat/shards|grep UNASSIGNED % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 30528 100 30528 0 0 705k 0 --:--:-- --:--:-- --:--:-- 745k graylog_83 1 p UNASSIGNED graylog_83 1 r UNASSIGNED graylog_83 0 p UNASSIGNED graylog_83 0 r UNASSIGNED graylog_82 1 p UNASSIGNED graylog_82 1 r UNASSIGNED graylog_85 2 p UNASSIGNED graylog_85 2 r UNASSIGNED graylog_85 1 p UNASSIGNED graylog_85 1 r UNASSIGNED graylog_84 0 p UNASSIGNED graylog_84 0 r UNASSIGNED graylog_87 1 p UNASSIGNED graylog_87 1 r UNASSIGNED graylog_86 3 p UNASSIGNED graylog_86 3 r UNASSIGNED graylog_86 1 p UNASSIGNED graylog_86 1 r UNASSIGNED graylog_89 3 p UNASSIGNED graylog_89 3 r UNASSIGNED graylog_88 1 p UNASSIGNED graylog_88 1 r UNASSIGNED graylog_88 0 p UNASSIGNED graylog_88 0 r UNASSIGNED 3)然后依次修改以上UNASSIGNED ,命令为: curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "allocate" : { "index" : "graylog_83", "shard" : 1, "node" : "Auq82gfGQVWgOBw6S7ajRQ", "allow_primary" : true } }] }' PS: index就是索引的名称:也就是graylog_88,graylog_86,graylog_87..... node:就是在哪个节点上执行; shared:分片的编号! 本文转自 shine_forever 51CTO博客,原文链接:http://blog.51cto.com/shineforever/1859734

优秀的个人博客,低调大师

openstack vm status ERROR 的修复

在做openstack的vm迁移的时候出现ERROR。无法启动虚拟机,也没有迁移成功。 在出现ERROR的时候在一个测试用的vm上,使用dashboard里面的重建功能也可恢复正常状态,并且数据也不会丢失还是和之前的一样。 恢复ERROR状态到active的方法如下: 找出该VM的id。 查找数据库的该id状态。 use nova; select * from instances where uuid='xxxxxx' \G; update instances set vm_state='active' where uuid='xxxxx'; update instances set power_state=1 where uuid='xxxxxx'; 硬重启该VM即可。 本文转自ting2junshui51CTO博客,原文链接:http://blog.51cto.com/ting2junshui/1744041 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

上手 WebRTC DTLS 遇到很多 BUG?浅谈 DTLS Fragment

上一篇《详解 WebRTC 传输安全机制:一文读懂 DTLS 协议》详细阐述了 DTLS。本文将结合 DTLS 开发中遇到的问题,详细解读 DTLS 的一些基础概念以及 Fragment 的机制,并进一步深究 DTLS 协议。 作者|泰一 审校|进学、莫战 前言 最近在做 J 和 G 这两套 RTC 系统的 DTLS-SRTP 握手加密工作,要求使用 CA 机构颁发的证书。在本机调试的过程中发现:G 系统使用 CA 证书,DTLS 握手成功,而 J 系统则握手失败。 经过几番调试与分析,定位到了原因:J 系统相较于 G 系统多了一个 TURN 转发模块,该模块设置的接收缓冲区的上限值为 1600 字节,而 CA 证书的大小则有近 3000 字节,因此 TURN 模块转发给客户端的证书不完整,导致 DTLS 握手失败。 大家都知道, WebRTC 的 DTLS 使用的是自签名的证书,这个证书一般不会太大,如下图所示,只有 286 字节。 然而,如果要使用 CA 颁发的证书,那么这个证书可能会很大,如下图所示,竟达到了 2772 字节,显然超出了 TURN 模块的接收缓冲区的大小。 上图中,你可能注意到了这个 CA 证书被分成了两片(two fragments),这其实是 DTLS 协议层做的。不过值得思考的是,CA 证书的每一片的大小都未超出 TURN 模块接收缓冲区的 1600 字节的限制,但是为什么 J 系统的 TURN 转发模块依然会接收失败呢? 这是因为证书虽然被分片,但是在发送到 TURN 模块时并没有按照分片独立发送,仍然是全部打包到了同一个 UDP 数据报中进行发送,所以接收肯定会失败。 下面,我们将一起了解下 DTLS Fragment 的机制。首先要理清几个概念。 Message、Record、Flight DTLS 协议分为两层:底层的 record protocol 和上层的 handshake protocol、change cipher spec protocol、alert protocol 以及 application data protocol。 Remark:握手协议、密码规格变更协议、警告协议、应用数据协议均在 DTLS 记录协议的上层,这四种协议统称为 DTLS 握手协议。 Note:关于记录和握手这两层协议各自的作用,这里就不再赘述,可以参考 WebRTC 中 DTLS 的应用。 DTLS Message 是一条完整的 DTLS 消息。比如握手消息:Client Hello、Certificate、Client Key Exchange 等;比如密码规格变更消息:Change Cipher Spec。 DTLS Record 是记录层(Record Layer)的概念,可以认为它是一个壳子,里面装载着 DTLS Message,如下图: Message 和 Record 是一对一或者一对多的关系。也就是说,一个 Record 不一定装了一条完整的 Message。因为有可能是多个 Record 组成一个完整的 Message。 如果 Message 很小,未超过 MTU 的限制,那么一个 Record 足以装下一条 Message;如果 Message 很大,超过 MTU 的限制,那么就需要多个 Record 来装这条 Message。即这条 DTLS Message 会被分割为多个 Fragment,然后分别装入多个 Record。 Remark:最大传输单元(Maximum transmission Unit, MTU)是数据链路层的概念,MTU 限制的是数据链路层的 payload 大小,也就是其上层协议的大小,比如 IP、ICMP。在以太网中,链路层的 MTU 是 1500 字节。 比如,Certificate 这个握手消息,证书大小很容易就超过 MTU 的限制,那么这个消息就会被分割为多个 Fragment 并被分别存放到多个 DTLS Record,每个 Fragment 的大小要保证不超过 MTU 的限制(PS:导读的第二张图就是一个实际的例子)。 Flight 中文解释为 “航班” 或者 “航程”,是一个或者一组打包好的 Message,这组 Message 属于同一个 “航程”,视为一个整体,通过单个 UDP 数据报发送。 如上图所示,本次 DTLS 握手一共有 4 个 Flight。Flight2 是 Server Hello、Certificate、Server Hello Done 这三条 Message 的组合,其中 Certificate 这条 Message 被分割为两个 Fragment,装到两个 Record 中。Flight2 通过大小为 2969 字节的 UDP 数据报发送出去。 Remark:Flight2 这个 2969 字节的 UDP 包是在本机环境下调试、抓包得到的,并不代表 MTU 有这么大,在实际的网络中,不会出现这种远超 MTU 限制的数据包。 到这里,关于 Message、Record、Flight 的概念就讲完了,三者之间的关如下图: Fragment 下面我们谈谈,DTLS 为什么要对 DTLS Message 做分片。 我们知道,受以太网 MTU 影响,UDP 数据报最大为 1500 字节,超出这个限制就会被 IP 层分片(PS:以太网 MTU 设置为 1500 字节是为了最大化信道传输利用率)。 但是如果 IP 层分片机制被禁止呢?这就会导致大于 1500 字节的 UDP 数据报在 IP 层被丢弃。因此,DTLS 要对消息做分片,来满足 IP 层对报文大小的要求。DTLS1.2: Message Size 这一节解释了这个原因。 By contrast, UDP datagrams are often limited to < 1500 bytes if IP fragmentation is not desired. In order to compensate for this limitation, each DTLS handshake message may be fragmented over several DTLS records, each of which is intended to fit in a single IP datagram. 因此,DTLS 的分片机制很简单:在发送时把 DTLS Message 分割成多个连续的 DTLS Record,在接收时缓存分片,直到拥有完整的 DTLS Message。 我们可以使用 OpenSSL 的这两个 API 设置 MTU 的大小: SSL_set_options(dtls, SSL_OP_NO_QUERY_MTU); SSL_set_mtu(dtls, 1500); 上面的代码设置了 MTU 为 1500,那么当 DTLS Message 大小超过 1500 字节,就会触发 DTLS 的分片机制,同理,如果设置 MTU 为 300,那么当 DTLS Message 大小超过 300 字节,就会分片。如果不进行设置,那么 MTU 会走默认值,如下图所示,证书消息被分割成了若干个大小为 288 字节的固定的 Fragment。 Remark:TLS 底层是 TCP 协议,为字节流式传输,因此 TLS 没有消息分片机制。 我们还可使用下面的 API 设置 Fragment 的大小的上限: SSL_set_max_send_fragment(dtls, 1500); 最后,我们回到导读描述的问题:证书消息实际上确实被分割为两片并分别存储到两个 Record,但是由于在发送的时候还是打包到了一个 UDP 数据报,因此,过大的 UDP 数据报导致 TURN 模块并未接收完整。 更详细的原因是:我们使用的是内存型的 BIO,在应用层调用 BIO_get_mem_data 得到的是关于 DTLS Message 的一块连续的内存(虽然这块内存中的证书消息已经被 DTLS 切成两个连续的 Fragment 并存在两个 Record 中),而应用层在获取到这块内存后就直接通过 sendto 函数发送给了对端,因此,这个 UDP 报文当然还是特别大,导致接收失败。 回过头来再看下导读中证书消息分片的这张图,两个 Record 的 message sequence 字段值相同,说明这是同一个 DTLS Message 的两个 Fragment。且每个 Record 都有 fragment offset 和 fragment length 这两个字段,用来标识分片的边界。所以,我们可以根据这两个字段去解析出每一个独立的 Fragment。 当然,根据 Record 头部的 Length 字段足以确定边界,这会使应用层的解析更加方便。所以,要解决这个问题,应用层要做的是:对从 BIO 获取到的这块消息内存进行解析,得到每个 Record 的边界,然后将每个 Record 以独立的 UDP 报文发送出去。具体的解析代码这里就不贴出来了,非常简单。 最后,在实践中发现,DTLS Record 不能跨 UDP 数据报发送,DTLS 1.2: Transport Layer Mapping 这一节也交代了这一点。也就是说,应用层要严格的按照 Record 的边界解析出每一个 Record,分别通过独立的 UDP 数据报发送,而不能按照自己的意愿随意划分为若干个 UDP 数据报发送。因为这可能会导致某个 DTLS Record 被切分到多个 UDP 数据报发送,从而导致接收端 DTLS 无法将收到的 DTLS Records 重组为完整的 DTLS Message。 下图是 DTLS 分片独立发送后的效果: 有兴趣的读者可以参考我写的 DTLS demo,它实现了简单的 DTLS 握手和分片独立发送。也可以参考 开源视频服务器 SRS 的 DTLS 实现,更加简洁和详尽。 总结 对于超过 MTU 限制的 DTLS Message,DTLS 会把它分割为多个 Fragment, 并分别存储到各个 DTLS Record 中,因此一个 Fragment 一定是一个 DTLS Record。对于未超过 MTU 限制的 DTLS Message,则不会被分片,也是存储到 DTLS Record 中,因此一个 DTLS Record 不一定是一个 Fragment,也有可能是一个完整的 DTLS Message。另外,MTU 的大小以及 Fragment 的最大值都可以使用 OpenSSL 的 API 进行设置。 由于我们通过内存型 BIO 获取到了存储了各个 DTLS Message 的这块连续内存后,直接将其打包为 Flight,并通过单独的 UDP 数据报文发送,因此这个 UDP 包仍然还是那么大,超出了 TURN 模块接收缓冲区的上限和 MTU 的限制。所以为了做到真正的分片独立发送,需要应用层自己去做 Fragment 的解析(其实就是解析 Record 的边界),并分别通过独立的 UDP 报文发送。 我们在解决了一个问题后,还要再问一下自己有没有引入新的问题。 独立发送每个 DTLS Record,虽然解决了 DTLS Message 超过 MTU 限制的问题,但是这也增加了 UDP 报文的数量,因此丢包的概率也会相应的增加,DTLS 重传次数增加,握手的成功率降低。解决这个问题的一个方法是:不必每个 DTLS Record 都单独 UDP 发送,可以多个 DTLS Record 发送,只要能保证它们加起来的大小不超过 MTU 的限制就可以。 同时,我们也要问一下自己有没有更好的方法。 比如目前的解决方法是应用层自己实现 Record 解析并独立发送,那么 OpenSSL 是否已经有相关的 API 实现类似的功能,再比如 BIO 有没有相关的 API 可以告诉我们读取的内存数据中 Record 的数量以及每个 Record 的边界?这个问题,以后有时间再调研吧。 感谢阅读。 参考 DTLS 1.2 TLS 1.2 「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。公众号后台回复【技术】可加入阿里云视频云技术交流群,和作者一起探讨音视频技术,获取更多行业最新信息。

优秀的个人博客,低调大师

如何优雅地根治null值引起的Bug?!

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 常听到群里开发兄弟抱怨,实操时经常看到项目中存在到处空值判断的情况,这些判断,会让人觉得摸不着头绪,它的出现很有可能和当前的业务逻辑并没有关系。但着实头疼。。。 有时候,更可怕的是系统因为这些空值的情况,会抛出空指针异常,导致业务系统发生问题。本文总结了几种关于空值的处理手法,分享给大家。 业务中的空值 场景存在一个 UserSearchService用来提供用户查询的功能: 问题现场对于面向对象语言来讲,抽象层级特别的重要。尤其是对接口的抽象,它在设计和开发中占很大的比重,我们在开发时希望尽量面向接口编程。 对于以上描述的接口方法来看,大概可以推断出可能它包含了以下两个含义: listUser(): 查询用户列表 get(Integerid): 查询单个用户 在所有的开发中,XP推崇的TDD模式可以很好的引导我们对接口的定义,所以我们将TDD作为开发代码的”推动者”。对于以上的接口,当我们使用TDD进行测试用例先行时,发现了潜在的问题: listUser() 如果没有数据,那它是返回空集合还是null呢? get(Integerid) 如果没有这个对象,是抛异常还是返回null呢? 深入listUser研究 我们先来讨论 这段代码返回是null,从我多年的开发经验来讲,对于集合这样返回值,最好不要返回null,因为如果返回了null,会给调用者带来很多麻烦。你将会把这种调用风险交给调用者来控制。 如果调用者是一个谨慎的人,他会进行是否为null的条件判断。如果他并非谨慎,或者他是一个面向接口编程的狂热分子(当然,面向接口编程是正确的方向),他会按照自己的理解去调用接口,而不进行是否为null的条件判断,如果这样的话,是非常危险的,它很有可能出现空指针异常! 基于此,我们将它进行优化: 对于接口( ListlistUser()),它一定会返回List,即使没有数据,它仍然会返回List(集合中没有任何元素);通过以上的修改,我们成功的避免了有可能发生的空指针异常,这样的写法更安全! 深入研究get方法 对于接口 我们把接口定义加上了说明之后,调用者会看到,如果调用此接口,很有可能抛出“UserNotFoundException(找不到用户)”这样的异常。这种方式可以在调用者调用接口的时候看到接口的定义,但是,这种方式是”弱提示”的!关注微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的教程,都是干货。如果调用者忽略了注释,有可能就对业务系统产生了风险,这个风险有可能导致一个亿!除了以上这种”弱提示”的方式,还有一种方式是,返回值是有可能为空的。那要怎么办呢?我认为我们需要增加一个接口,用来描述这种场景.引入jdk8的Optional,或者使用guava的Optional.看如下定义: 深入入参 通过上述的所有接口的描述,你能确定入参id一定是必传的吗?我觉得答案应该是:不能确定。除非接口的文档注释上加以说明。那如何约束入参呢?推荐两种方式: 强制约束 文档性约束(弱提示) 1.强制约束,我们可以通过jsr 303进行严格的约束声明: 当然,这样写,要配合AOP的操作进行验证,但让spring已经提供了很好的集成方案,在此就不在赘述了。 2.文档性约束 在很多时候,我们会遇到遗留代码,对于遗留代码,整体性改造的可能性很小。我们更希望通过阅读接口的实现,来进行接口的说明。jsr 305规范,给了我们一个描述接口入参的一个方式(需要引入库 com.google.code.findbugs:jsr305):可以使用注解: @Nullable @Nonnull @CheckForNull 进行接口说明。比如: 小结 通过 空集合返回值,Optional,jsr 303,jsr 305这几种方式,可以让我们的代码可读性更强,出错率更低!空集合返回值 :如果有集合这样返回值时,除非真的有说服自己的理由,否则,一定要返回空集合,而不是nullOptional: 如果你的代码是jdk8,就引入它!如果不是,则使用Guava的Optional,或者升级jdk版本!它很大程度的能增加了接口的可读性!jsr 303: 如果新的项目正在开发,不防加上这个试试!一定有一种特别爽的感觉!jsr 305: 如果老的项目在你的手上,你可以尝试的加上这种文档型注解,有助于你后期的重构,或者新功能增加了,对于老接口的理解! 空对象模式 场景来看一个DTO转化的场景,对象: 优化修改这样的数据转化,可读性非常差,每个字段的判断,如果是空就设置为空字符串(“”)换一种思维方式进行思考,我们是拿到Person这个类的数据,然后进行赋值操作(setXXX),其实是不关系Person的具体实现是谁的。那我们可以创建一个Person子类: 其中 getPerson()方法,可以用来根据业务逻辑获取Person有可能的对象(对当前例子来讲,如果Person不存在,返回Person的的特例NUllPerson),如果修改成这样,代码的可读性就会变的很强了。 使用Optional可以进行优化 空对象模式,它的弊端在于需要创建一个特例对象,但是如果特例的情况比较多,我们是不是需要创建多个特例对象呢,虽然我们也使用了面向对象的多态特性,但是,业务的复杂性如果真的让我们创建多个特例对象,我们还是要再三考虑一下这种模式,它可能会带来代码的复杂性。 对于上述代码,还可以使用Optional进行优化。 Optional对空值的使用,我觉得更为贴切,它只适用于”是否存在”的场景。如果只对控制的存在判断,我建议使用Optional。Optioanl的正确使用Optional如此强大,它表达了计算机最原始的特性(0 or 1),那它如何正确的被使用呢!Optional不要作为参数如果你写了一个public方法,这个方法规定了一些输入参数,这些参数中有一些是可以传入null的,那这时候是否可以使用Optional呢?给的建议是: 一定不要这样使用!举个例子: 我觉得这样的语义更强,并且更能满足 软件设计原则中的 “单一职责”。如果你觉得你的入参真的有必要可能传null,那请使用jsr 303或者jsr 305进行说明和验证!请记住! Optional不能作为入参的参数! Optional作为返回值 当个实体的返回那Optioanl可以做为返回值吗?其实它是非常满足是否存在这个语义的。你如说,你要根据id获取用户信息,这个用户有可能存在或者不存在。你可以这样使用: 这样的返回结果,会让调用者不知所措,是否我判断Optional之后,还用进行isEmpty的判断呢?这样带来的返回值歧义!我认为是没有必要的。 我们要约定,对于List这种集合返回值,如果集合真的是null的,请返回空集合(Lists.newArrayList); 使用Optional变量 如果有这样的变量userOpt,请记住 : 一定不能直接使用get ,如果这样用,就丧失了Optional本身的含义 ( 比如userOp.get() ) 不要直接使用getOrThrow ,如果你有这样的需求:获取不到就抛异常。那就要考虑,是否是调用的接口设计的是否合理 getter中的使用 对于一个java bean,所有的属性都有可能返回null,那是否需要改写所有的getter成为Optional类型呢?给大家的建议是,不要这样滥用Optional.即便 我java bean中的getter是符合Optional的,但是因为java bean 太多了,这样会导致你的代码有50%以上进行Optinal的判断,这样便污染了代码。(我想说,其实你的实体中的字段应该都是由业务含义的,会认真的思考过它存在的价值的,不能因为Optional的存在而滥用)我们应该更关注于业务,而不只是空值的判断。不要在getter中滥用Optional. 小结 可以这样总结Optional的使用: 当使用值为空的情况,并非源于错误时,可以使用Optional! Optional不要用于集合操作! 不要滥用Optional,比如在java bean的getter中! 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/zhibo 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-07-09本文作者:互联网架构师本文来自:“互联网架构师”,了解相关信息可以关注“互联网架构师”

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册