• [技术干货] CSE Java SDK包名切换指导
    背景信息CSE Java SDK的开源部分ServiceComb项目已于2017年12月全票通过进入Apache孵化器,根据Apache软件基金会要求,项目groupId统一由io.servicecomb调整为org.apache.servicecomb。CSE Java SDK作为ServiceComb的商业版本,除提供对接华为公有云的能力、安全、分布式数据一致性等商业能力外,其大部分组件来自于开源的ServiceComb。因此提供本指导用于支持客户顺利升级至包名变更后的CSE Java SDK版本(2.3.3+)。更改说明CSE Java SDK版本(2.3.3+)中涉及包名变化情况如下:序号包名称groupId(修改前)groupId(修改后)变化类型1CSE Java-SDK开源包65个包名变更,详见CSE Java SDK开源包列表io.servicecomborg.apache.servicecomb修改2CSE Java-SDK开源包foundation-config-cc新增config-cc,groupId为org.apache.servicecomb新增3CSE Java-SDK商业包foundation-config-cc移除foundation-config-cc删除4CSE Java-SDK商业包共计13个,详见CSE Java SDK商业包列表com.huawei.paas.cse无变化操作步骤通过配置maven setting文件以获取SDK依赖。profiles中增加如下配置。<profile>     <id>nexusProfile</id>     <repositories>         <repository>             <id>cse1</id>             <url>http://maven.huaweicse.com/nexus/content/groups/public/</url>         </repository>     </repositories> </profile>新增activeProfiles配置。<activeProfiles>     <activeProfile>nexusProfile</activeProfile> </activeProfiles>引入dependencyManagement,建议开发者在pom.xml中进行如下配置以便更好的管理三方件。 说明:版本使用2.3.3以上版本。<dependencyManagement>     <dependencies>         <dependency>             <groupId>com.huawei.paas.cse</groupId>             <artifactId>cse-dependency</artifactId>             <version>2.3.58</version>             <type>pom</type>             <scope>import</scope>         </dependency>     </dependencies> </dependencyManagement>修改pom.xml中依赖包的groupid。此处仅以引入对spring-boot-starter-provider、cse-solution-service-engine、foundation-auth的依赖为例。修改前<dependency>     <groupId>io.servicecomb</groupId>     <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency>     <groupId>com.huawei.paas.cse</groupId>     <artifactId>cse-solution-service-engine</artifactId> </dependency> <dependency>     <groupId>com.huawei.paas.cse</groupId>     <artifactId>foundation-auth</artifactId>     <exclusions>         <exclusion>             <groupId>org.slf4j</groupId>             <artifactId>slf4j-log4j12</artifactId>         </exclusion>     </exclusions> </dependency>修改后<dependency>     <groupId>org.apache.servicecomb</groupId>     <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency>     <groupId>com.huawei.paas.cse</groupId>     <artifactId>cse-solution-service-engine</artifactId> </dependency> <dependency>     <groupId>com.huawei.paas.cse</groupId>     <artifactId>foundation-auth</artifactId>     <exclusions>         <exclusion>             <groupId>org.slf4j</groupId>             <artifactId>slf4j-log4j12</artifactId>         </exclusion>     </exclusions> </dependency>CSE Java SDK开源包列表序号artifactIdgroupid(修改前)groupid(修改后)1common-javassistio.servicecomborg.apache.servicecomb2common-protobufio.servicecomborg.apache.servicecomb3common-restio.servicecomborg.apache.servicecomb4commonio.servicecomborg.apache.servicecomb5config-apolloio.servicecomborg.apache.servicecomb6dynamic-configio.servicecomborg.apache.servicecomb7edge-coreio.servicecomborg.apache.servicecomb8edgeio.servicecomborg.apache.servicecomb9foundation-commonio.servicecomborg.apache.servicecomb10config-ccio.servicecomborg.apache.servicecomb11foundation-configio.servicecomborg.apache.servicecomb12foundation-metricsio.servicecomborg.apache.servicecomb13foundation-sslio.servicecomborg.apache.servicecomb14foundation-test-scaffoldingio.servicecomborg.apache.servicecomb15foundation-vertxio.servicecomborg.apache.servicecomb16foundationsio.servicecomborg.apache.servicecomb17handler-bizkeeperio.servicecomborg.apache.servicecomb18handler-flowcontrol-qpsio.servicecomborg.apache.servicecomb19handler-loadbalanceio.servicecomborg.apache.servicecomb20handler-publickey-authio.servicecomborg.apache.servicecomb21handler-tracing-zipkinio.servicecomborg.apache.servicecomb22handlersio.servicecomborg.apache.servicecomb23java-chassis-coreio.servicecomborg.apache.servicecomb24java-chassis-dependenciesio.servicecomborg.apache.servicecomb25java-chassis-parentio.servicecomborg.apache.servicecomb26java-chassisio.servicecomborg.apache.servicecomb27metrics-commonio.servicecomborg.apache.servicecomb28metrics-coreio.servicecomborg.apache.servicecomb29metrics-extensionio.servicecomborg.apache.servicecomb30metrics-integrationio.servicecomborg.apache.servicecomb31metrics-prometheusio.servicecomborg.apache.servicecomb32metricsio.servicecomborg.apache.servicecomb33provider-jaxrsio.servicecomborg.apache.servicecomb34provider-pojoio.servicecomborg.apache.servicecomb35provider-rest-commonio.servicecomborg.apache.servicecomb36provider-springmvcio.servicecomborg.apache.servicecomb37providersio.servicecomborg.apache.servicecomb38service-registryio.servicecomborg.apache.servicecomb39spring-boot-starter-configurationio.servicecomborg.apache.servicecomb40spring-boot-starter-discoveryio.servicecomborg.apache.servicecomb41spring-boot-starter-parentio.servicecomborg.apache.servicecomb42spring-boot-starter-providerio.servicecomborg.apache.servicecomb43spring-boot-starter-registryio.servicecomborg.apache.servicecomb44spring-boot-starter-servicecombio.servicecomborg.apache.servicecomb45spring-boot-starter-transportio.servicecomborg.apache.servicecomb46spring-cloud-zuul-zipkinio.servicecomborg.apache.servicecomb47spring-cloud-zuulio.servicecomborg.apache.servicecomb48swagger-generator-coreio.servicecomborg.apache.servicecomb49swagger-generator-jaxrsio.servicecomborg.apache.servicecomb50swagger-generator-springmvcio.servicecomborg.apache.servicecomb51swagger-generatorio.servicecomborg.apache.servicecomb52swagger-invocation-coreio.servicecomborg.apache.servicecomb53swagger-invocation-jaxrsio.servicecomborg.apache.servicecomb54swagger-invocation-springmvcio.servicecomborg.apache.servicecomb55swagger-invocationio.servicecomborg.apache.servicecomb56swaggerio.servicecomborg.apache.servicecomb57tracing-commonio.servicecomborg.apache.servicecomb58tracing-zipkinio.servicecomborg.apache.servicecomb59tracingio.servicecomborg.apache.servicecomb60transport-highwayio.servicecomborg.apache.servicecomb61transport-rest-clientio.servicecomborg.apache.servicecomb62transport-rest-servletio.servicecomborg.apache.servicecomb63transport-rest-vertxio.servicecomborg.apache.servicecomb64transport-restio.servicecomborg.apache.servicecomb65transportsio.servicecomborg.apache.servicecombCSE Java SDK商业包列表增删说明序号artifactIdgroupid(不涉及修改)1foundation-config-cc已迁移至ServiceCombCSE Java-SDK商业包列表序号artifactIdgroupid(不涉及修改)1cse-adapter-springmvccom.huawei.paas.cse2cse-dependencycom.huawei.paas.cse3cse-handler-2pccom.huawei.paas.cse4cse-handler-cloud-extensioncom.huawei.paas.cse5cse-handler-performance-statscom.huawei.paas.cse6cse-handler-tcccom.huawei.paas.cse7cse-handler-tracing-apmcom.huawei.paas.cse8cse-handler-tracingcom.huawei.paas.cse9cse-narayanacom.huawei.paas.cse10cse-solution-service-enginecom.huawei.paas.cse11cse-solutionscom.huawei.paas.cse12foundation-authcom.huawei.paas.cse13paas-csecom.huawei.paas.cse
  • [视频点播] 使用PHP SDK,web端的华为云视频点播接入,加密视频播放的坑-解坑篇
    一路走过来终于把如何使用php sdk梳理好了,我把期间遇到的问题列出来,希望以后的人不会走弯路。1、背景我已经按步骤设置了转码模板,选择的是hls和2.64的模式用于加密;同时上传了视频,同时转码成功了;最后我设置好了防盗链的白名单和加密设置里面的秘钥url。我先后设置了两个域名www.a.com、www.b.com。2、坑第一、由于需求,需要将a域名改为b域名,同时将ab两个域名加入了防盗链,于是乎我就将获取秘钥的url从www.a.com改为www.b.com,在此情况下,奇怪的事情,我点击现在域名下面的播放链接在手机上能播放,但是我b域名下的里程序并没有将key写进存放key的文件里。 查找过程,将播放页面视频放入pc的web上查看网络连接,发现视频请求秘钥的链接还是请求的a域名的秘钥地址,经过漫长的寻觅,终于发现原来上传视频转码时已经将秘钥地址写入了m3u8,因此,我又重新设置了当前b域名下的秘钥地址,并重新上传转码,在查看网络请求时已经改为了b域名下的秘钥地址,所以一定要注意,一旦更改了获取秘钥的地址,一定要重新上传转码一次才能正常请求。第二、在设置防盗链时的白名单和空referer时给了我极大的困扰,点击后面的灰色问号,显示的是https能访问,并没有提http可以访问,在此情况下,我先后将域名加了证书,发现加证书的访问不能进行,而http是可以访问成功播放的。这里我总结的是,https应该是可以访问的,前提是你要设置好自己服务器的443端口的访问以及各种配置和转码都要是https统一才行,我采用的方法是都没有采用https,统一为http能成功,我们在理解华为云的文档时要注意了,希望以后能更明确一些。第三,在开发之前,我始终没有理解到我们在系统中设置的获取秘钥key是什么时候可以调用,通过我在pc端查看请求时才知道,js会根据请求的m3u8去解析里面的秘钥地址,会带上token一直请求直到请求成功这个地址,在这这里租户系统可以获取这个token进行验证。
  • [大咖交流] Istio调用链埋点原理剖析—是否真的“零修改”分享实录(上)
    本文整理自华为Cloud BU技术专家在K8S技术社上关于Istio调用链的分享。前言大家好,我是idouba,来自华为Cloud BU,当前在做Istio服务网格在华为云容器服务的产品化工作。今天跟大家分享的主题是Istio调用链相关内容。通过剖析Istio的架构机制与Istio中调用链的工作原理来解答一个大家经常问道的一个问题:Istio是否像其官方文档中宣传的一样,对业务代码完全的无侵入,无需用做任何修改就可以完成所有的治理能力,包括调用链的埋点?关于这个问题,可以提前透漏下,答案是让人有点沮丧的,得改点。在Isito中你不用在自己的代码里使用各种埋点的SDK来做埋点的逻辑,但是必须要有适当的配合的修改。为什么本来无侵入的Service Mesh形态的技术却要求我们开发者修改些代码,到底要做哪些修改?Istio中调用链到底是怎么工作的?在下面的内容中将逐个回答这些问题。本次分享的主题包括两部分: 第一部分作为背景和基础,介绍Istio的架构和机制;第二部分将重点介绍Istio调用链的相关内容,解答前面提出的几个问题。Isito的架构和机制Service Mesh如官方介绍,Istio是一个用于连接、控制、保护和观测服务的一个开放平台。即:智能控制服务间的流量和API调用;提供授权、认证和通信加密机制自动保护服务安全;并使用各种策略来控制调用者对服务的访问;另外可以扩展丰富的调用链、监控、日志等手段来对服务的与性能进行观测。Istio是Google继Kubernetes之后的又一重要项目,提供了Service Mesh方式服务治理的完整的解决方案。2017年5月发布第一个版本 0.1, 2018年6月1日发布了0.8版本,第一个LTS版本,当前在使用的1.0版本是今年7.31发布,对外宣传可用于生产。最新的1.1版本将2018.11中旬最近发布(当时规划实际已延迟,作者注)。Istio属于Service Mesh的一种实现。通过一张典型图来了解下Service Mesh。如图示深色是Proxy,浅色的是服务,所有流入流出服务的都通过Proxy。Service Mesh正是由这一组轻量代理组成,和应用程序部署在一起,但是应用程序感知不到他的存在。特别对于云原生应用,服务间的应用访问拓扑都比较复杂,可以通过Service Mesh来保证服务间的调用请求在可靠、安全的传递。在实现上一般会有一个统一的控制面,对这些代理有个统一的管理,所有的代理都接入一个控制面。对代理进行生命期管理和统一的治理规则的配置。这里是对Service Mesh特点的一个一般性描述,后面结合Isito的架构和机制可以看下在Istio中对应的实现。可以看到Service Mesh最核心的特点是在Proxy中实现治理逻辑,从而做到应用程序无感知。其实这个形态也是经过一个演变的过程的:最早的治理逻辑直接由业务代码开发人员设计和实现,对服务间的访问进行管理,在代码里其实也不分治理和业务,治理本身就是业务的一部分。这种形态的缺点非常明显就是业务代码和治理的耦合,同时公共的治理逻辑有大量的重复。很容易想到封装一个公共库,就是所谓的SDK,使用特定的SDK开发业务,则所有治理能力就内置了。Spring Cloud和Netflix都是此类的工具,使用比较广泛,除了治理能力外,SDK本身是个开发框架,基于一个语言统一、风格统一的开发框架开发新的项目非常好用。但这种形态语言相关,当前Java版本的SDK比较多。另外对于开发人员有一定的学习成本,必须熟悉这个SDK才能基于他开发。最重要的是推动已经在用的成熟的系统使用SDK重写下也不是个容易的事情。比如我们客户中就有用C开发的系统,运行稳定,基本不可能重写。对这类服务的治理就需要一个服务外面的治理方式。于是考虑是否可以继续封装,将治理能力提到进程外面来,作为独立进程。即Sidecar方式,也就是广泛关注的Service Mesh 的。真正可以做到对业务代码和进程0侵入,这对于原来的系统完全不用改造,直接使用Sidecar进行治理。用一段伪代码来表示以上形态的演变:可以看到随着封装越来越加强,从公共库级别,到进程级别。对业务的侵入越来越少,SDK的公共库从业务代码中解耦,Sidecar方式直接从业务进程解耦了。对应的治理位置越来越低,即生效的位置更加基础了。尤其是Service Mesh方式下面访问通过 Proxy执行治理,所以Service Mesh的方式也已被称为一种应用的基础设施层,和TCP/IP的协议栈一样。TCP/IP负责将字节流可靠地在网络节点间传递;而应用基础设施则保证服务间的请求在安全、可靠、可被管控的传递。这也对应了前面Istio作为Service Mesh一种实现的定位。Istio 关键能力Istio官方介绍自己的关键能力如上所示,我把它分为两部分:一部分是功能,另有一部分提供的扩展能力。功能上包括流量管理、策略执行、安全和可观察性。也正好应对了首页的连接、保护、控制和观测四大功能。流量管理:是Istio中最常用的功能。可以通过配置规则和访问路由,来控制服务间的流量和API调用。从而实现负载均衡、熔断、故障注入、重试、重定向等服务治理功能,并且可以通过配置流量规则来对将流量切分到不同版本上从而实现灰度发布的流程。策略执行:指Istio支持支持访问控制、速率限制、配额管理的能力。这些能力都是通过可动态**的策略控制后端实现。安全:Istio提供的底层的安全通道、管理服务通信的认证、授权,使得开发任务只用关注业务代码中的安全相关即可。可观察性:较之其他系统和平台,Istio比较明显的一个特点是服务运行的监控数据都可以动态获取和输出,提供了强大的调用链、监控和调用日志收集输出的能力。配合可视化工具,运维人员可以方便的看到系统的运行状况,并发现问题进而解决问题。我们这次分享的主题调用链也正是Isito可观察性的一个核心能力。后面分析可以看到以上四个特性从管理面看,正好对应Istio的三个重要组件。扩展性:主要是指Istio从系统设计上对运行平台、交互的相关系统都尽可能的解耦,可扩展。这里列出的特性:平台支持:指Istio可以部署在各种环境上,支持Kubernetes、Consul等上部署的服务,在之前版本上还支持注册到Eureka上的Service,新版本对Eureka的支持被拿掉了;集成和定制:指的Istio可以动态的对接各种如访问控制、配额管理等策略执行的后端和日志监控等客观性的后端。支持用户根据需要按照模板开发自己的后端方便的集成进来。其实这两个扩展性的能力正好也对应了Istio的两个核心组件Pilot和Mixer,后面Isito架构时一起看下。Istio 总体架构以上是Isito的总体架构。上面是数据面,下半部分是控制面。数据面Envoy是一个C++写的轻量代理,可以看到所有流入流出服务的流量都经过Proxy转发和处理,前面Istio中列出的所有的治理逻辑都是在Envoy上执行,正是拦截到服务访问间的流量才能进行各种治理;另外可以看到Sidecar都连到了一个统一的控制面。Istio其实专指控制面的几个服务组件:Pilot:Pilot干两个事情,一个是配置,就是前面功能介绍的智能路由和流量管理功能都是通过Pilot进行配置,并下发到Sidecar上去执行;另外一个是服务发现,可以对接不同的服务发现平台维护服务名和实例地址的关系并动态提供给Sidecar在服务请求时使用。Pilot的详细功能和机制见后面组件介绍。Mixer:Mixer是Istio中比较特殊,当前甚至有点争议的组件。前面Isito核心功能中介绍的遥测和策略执行两个大特性均是Mixer提供。而Istio官方强调的集成和定制也是Mixer提供。即可以动态的配置和开发策略执行与遥测的后端,来实现对应的功能。Mixer的详细功能和机制见后面组件介绍。Citadel:主要对应Istio核心功能中的安全部分。配合Pilot和Mixer实现秘钥和证书的管理、管理授权和审计,保证客户端和服务端的安全通信,通过内置的身份和凭证提供服务间的身份验证,并进而该通基于服务表示的策略执行。Isito主要组件Pilot如Istio架构中简介,Pilot实现服务发现和配置管理的功能。作为服务发现,Pilot中定义了一个抽象的服务模型,包括服务、服务实例、版本等。并且只定义的服务发现的接口,并未实现服务发现的功能,而是通过Adapter机制以一种可扩展的方式来集成各种不同的服务发现,并转换成Istio通用的抽象模型。 如在Kubernetes中,Pilot中的Kubernetes适配器通过Kube-APIServer服务器得到Kubernetes中对应的资源信息。而对于像Eureka这种服务注册表,则是使用一个Eureka的HTTP Client去访问Eureka的名字服务的集群,获取服务实例的列表。不管哪种方式最终都转换成Pilot的标准服务发现定义,进而通过标准接口提供给Sidecar使用。而配置管理,则是定义并维护各种的流量规则,来实现负载均衡、熔断、故障注入、流量拆分等功能。并转换成Envoy中标准格式推送给Envoy,从而实现治理功能。所有的这些功能用户均不用修改代码接口完成。详细的配置方式可以参照Istio Traffic Routing中的规则定义。重点关注:VirtualService、 DestinationRule、 Gateway等规则定义。如可以使用流量规则来配置各种灰度发布,也可以通过注入一个故障来测试故障场景;可以配置熔断来进行故障恢复;并且可以对HTTP请求根据我们的需要进行重定向、重写,重试等操作。Istio主要组件MixerMixer是Isito特有的一个组件。主要做两个功能Check和Report,分别对应Istio官方宣传的两个重大特性策略执行和遥测功能。逻辑上理解每次服务间的请求都会通过proxy连接Mixer来进行处理,由Mixer来将请求派发到对应的后端上处理。通过扩展不同的后端来增强Mixer的能力。如可以做访问控制、配额等这样的控制,也可以对接不同的监控后端来做监控数据的收集,进而提供网格运行的可观察性能力。Mixer通过使用通用插件模型实现的对接不同后端,避免了proxy为了完成不同的功能而去对接各种不同的后端。每个插件都被称为Adapter。对于每个请求Sidecar会从每一次请求中收集相关信息,如请求的路径,时间,源IP,目地服务,tracing头,日志等,并请这些属性上报给Mixer。Mixer和后端服务之间是通过适配器进行连接的,Mixer将Sidecar上报的内容通过适配器发送给后端服务。可以在不停止应用服务的情况下动态切换后台服务。除了可以通过adapter机制接入不同的后端,mixer还支持根据需要定义收集的metric,和对metric的处理方式,如样例所示,可以自定义监控指标。后面我们会看到Istio中调用链的数据也可以通过Mixer来收集。Istio和Kubernetes的天然结合尽管Isito强调自己的可扩展性的重要一点就是可以适配各种不同的平台,但实际场景上,甚至看Istio当前代码、设计可以发现其所有重要的能力都是基于Kubernetes展开的。Istio与Kubernetes结合之紧密,甚至有描述说看上去是一个团队开发的。即Istio就是基于Kubernetes之上,对Kubernetes能力的补齐。从功能场景看,Kubernetes提供了部署、升级和有限的运行流量管理能力;利用Service的机制来做服务注册和发现,转发,通过Kubeproxy有一定的转发和负载均衡能力。但是往上的如熔断、限流降级、调用链等治理能力就没有了。前面的功能介绍可以发现Istio很好的补齐了Kubernetes在服务治理上的这部分能力。即Kubernetes提供了基础服务运行能力,而Istio基于其上提供服务治理能力,对Kubernetes服务的治理能力。除了功能互补外,从形态上看Istio也是基于Kubernetes构建的。包括: Sicecar 运行在Kubernetes Pod里,作为一个Proxy和业务容器部署在一起,部署过程对用户透明。Mesh中要求业务程序的运行感知不到Sidecar的存在,基于Kubernetes的pod的设计这部分做的更彻底,对用户更透明,通过Isito的自动注入用户甚至感知不到部署Sidecar的这个过程,和部署一个一般的Deployment没有任何差别。试想如果是通过VM上部署一个Agent,不会有这么方便。另外Istio的服务发现也是非常完美基于Kubernetes的域名访问机制构建。Isito中的服务就是Kubernetes的服务,避免了之前使用独立的微服务框架在Kubernetes上运行时两套名字服务的尬尴和困惑。机制上Pilot通过在kubernetes里面注册一个controller来监听事件,从而获取Service和Kubernetes的Endpoint以及Pod的关系,并将这些映射关系转换成为Istio的统一抽象模型下发到Envoy进行转发。Istio所有的我们熟悉的路由规则、控制策略都是通过Kubernetes CRD表达,不需要一个单独的APIserver和后端的配置管理。所以Istio APIServer就是Kubernetes的KubeAPIServer,数据也当然的存在了对应Kubernetes的ETCD中。就连Istio的命令行工具Istioctl都是类似Kubectl风格的功能,提供基于命令行的配置功能。
  • [交流吐槽] 开发者文档里,提到的java mqtt sdk何时能提供
    我手上有树莓派,想知道如何接入OC平台。提交工单后,反馈sdk不提供
  • [技术干货] CSE JAVA SDK: java.lang.IllegalStateException: Response is closed 原因和定位
    当有些业务处理比较耗时的时候,日志里面经常打印如下异常:2019-01-09 10:42:22,890 [ntloop-thread-0] ERROR Unhandled exception [io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:345)]java.lang.IllegalStateException: Response is closedat io.vertx.core.http.impl.HttpServerResponseImpl.checkValid(HttpServerResponseImpl.java:548)at io.vertx.core.http.impl.HttpServerResponseImpl.end0(HttpServerResponseImpl.java:401)at io.vertx.core.http.impl.HttpServerResponseImpl.end(HttpServerResponseImpl.java:319)at org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse.internalFlushBuffer(VertxServerResponseToHttpServletResponse.java:122)at org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse.lambda$flushBuffer$0(VertxServerResponseToHttpServletResponse.java:112)at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:339)at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.lang.Thread.run(Thread.java:745)这个异常表示的是在给请求返回结果的时候,写结果发现连接已经关闭。这种情况通常发生在业务处理比较长的情况。这个日志在服务端打印(服务端是相对的)。和这个问题相关的配置由如下几个:客户端:cse.rest.client.connection.idleTimeoutInSeconds(缺省值30s)服务端:cse.rest.server.connection.idleTimeoutInSeconds(缺省值30s)如果业务处理时间超过这两个值的最小值,那么服务端就会报告这个异常。 
  • [技术干货] CSE JAVA SDK如何配置业务处理线程池
    CSE JAVA SDK的线程池模型比较复杂,对于tomcat场景,以及Edge Service的vert.x场景,都有一个业务处理线程池(Edge Service的场景默认在reactive模式,是没有业务线程池的)。CSE设置的默认线程池的线程个数为2 * CPU个数。如果部分服务处理比较慢(比如评价时延>50ms),那么建议要设置一个较大的业务线程池,以提升吞吐量。如果所有接口都处理的很快,则不需要设置非常大的业务线程池,过多线程反而会因为线程调度,增加处理时延。如果一个微服务,有少量的几个接口处理非常耗时,需要考虑将这些接口放到独立的线程池执行(线程池隔离),防止访问慢的接口,影响访问快的接口。     线程池配置 (可以适当的抽时间学习下线程模型: https://bbs.huaweicloud.com/blogs/0a1a862f412611e89fc57ca23e93a89f)        通过配置项servicecomb.executors.default给业务接口制定执行线程池。配置项的的缺省值为servicecomb.executor.groupThreadPool,这个值是Bean的ID,CSE缺省的几个Bean ID如下:  <bean id="cse.executor.groupThreadPool" class="org.apache.servicecomb.core.executor.FixedThreadExecutor"/>   <alias name="cse.executor.groupThreadPool" alias="cse.executor.default"/>   <alias name="cse.executor.groupThreadPool" alias="servicecomb.executor.groupThreadPool"/>   <bean id="cse.executor.reactive" class="org.apache.servicecomb.core.executor.ReactiveExecutor"/>   <alias name="cse.executor.reactive" alias="servicecomb.executor.reactive"/>  2.       通过servicecomb.executors.Provider.[servicename.schemaid.operationId]给某个具体的接口指定不同的线程池。
  • [视频点播] 使用PHP SDK,web端的华为云视频点播接入,加密视频播放、demo跑起来 -代码篇
    对于代码方面主要涉及到如下的代码:1、web端自动获取核对的秘钥接口如图这个url的主要代码结合文档可以如下,主要使用到了php的json转数组函数和base64_decode函数:<?php /**  * 查询媒资密钥  */ require './cloudvod/vod/service/AssetService.php'; require './cloudvod/vod/model/QueryAssetCiphersReq.php'; $req = new QueryAssetCiphersReq(); $req ->setAssetId('0718d0ac557e702f2cff78df3021fcf8'); $rsp = ""; try {     $rsp = AssetService::QueryAssetCiphers($req);     $rspp=json_decode($rsp->getBody());         echo base64_decode($rspp->dk); } catch (Exception $e) {     echo $e; } ?>2、前端播放器的代码,代码可以参考音视频管理-》管理,查看示例代码,直接黏贴过来:<!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <meta http-equiv="x-ua-compatible" content="chrome=1,ie=edge">     <!--[if lt IE 9]>     <script  src="http://media-cache.huaweicloud.com/video/hwplayer/0.0.6/lib/video-js-5.20.5/ie8/videojs-ie8.min.js?ttl=1828668305"></script>     <![endif]-->     <script  src="http://media-cache.huaweicloud.com/video/hwplayer/0.0.6/dist/hwplayer.js?ttl=1828668305"></script> </head> <body> <video controls id="test" width="480" height="300" class="video-js  vjs-default-skin vjs-big-play-centered"> </video> <script>     hwplayerloaded(function () {         var player = new HWPlayer("test",{             width: 480,             height: 300,             controls: true         },function(){             //播放器加载完成执行的逻辑                      });         player.src({             src: "https://613.cdn-vod.huaweicloud.com/asset/0718d0ac220exxxf2cff78df3021fcf8/play_video/11111111111111111111111111111111/add626b8dxxxx46d63498048f3cba3_1_1280X720_1500_0.m3u8",             type: "application/x-mpegURL"         });     }); </script> </body> 3、phpsdk的引入,在下载sdk解压后,为了减少require_once引入而发生错误,建议根据实际的情况将里面的相对路径改为绝对路径,改的方法很多,可以通过变量等方法。根据华为的开发文档,在init.php文件中填写自己的ak、sk、projectid。 4、以上相关的代码,是没有考虑到租户系统认证的token的代码,这个将在下一篇进行介绍。
  • [视频点播] 使用PHP SDK,web端的华为云视频点播接入,加密视频播放
    背景:由于公司近期有视频点播的需求,且要求视频不能被盗链和下载,因此看了华为云视频服务中的文档后,觉得适合我们的需求。于是我看了所有的文档与相应的文档,包括java的sdk和php的sdk代码,经过一天的摸索,终于在前端页面看到了我要播放的视频。总体来说大致是这样几个步骤:1、全局设置选项里面设置转码模板,记得打开加密和视频格式HLS,其他随便选择。2、视频点播控制台上传视频,具体步骤参考相关官方文档。3、在视频管理选项里面点击转码,打开查看详情,此时请记住HLS的播放地址结尾为m3u8。4、全局设置-》安全设置-》HLS加密,填入一个自己服务器能访问的地址,功能是调用华为云点播接口,接口返回的数据为json格式,可以用json_decode转为数组,然后用base64.decode数组里面的明文值,这个值用echo输出,return没试过。5、视频管理-》选择视频的详情-》查看网页演示代码,将代码复制黏贴到自己的网站目录下。6、在网页的html中的js代码player.src后面地址改写成这样http://{domain}/asset/{asset_id}/play_video/{token}/index.m3u8,其中token为32位,前期跑demo的时候可以随便写一个。7、网页打开浏览既可以观看。总结:1、token只是用于客户端与自己服务器之间的合法性访问。2、华为云文档上说的秘钥说了一大堆,结果所有的工作都在web页面引入华为指定的js时已经完成了,无需关注。3、在设计上,秘钥接口不要频繁请求,官方文档里推荐把秘钥存入缓存,可以判断缓存里时候有秘钥,有的话直接返回,没有的就请求接口存入缓存;另外,秘钥的核对是华为云自动进行的,在播放视频时引入的华为云js会自动核验。因此,可以这样设计代码,以mvc为例:1、播放器页面的控制器生成token存入缓存中,并把token渲染在页面上的其他地方,播放器的播放地址此次的url中不包括token的字符串。2、播放器播放按钮点击,将在页面中的token上传到自己的服务器检验是否有效,如验证成功,将token拼接至url里,动态覆盖播放器的播放地址进行播放请求。3、代码见下一篇。
  • [技术干货] InstanceCacheChecker: |instance cache not match
    早期的服务中心版本存在一个bug。当实例下线的时候,revision信息没有变化,SDK感知不到实例下线。 SDK为了检测这个BUG,做了一个功能,会定时(缺省是24小时)检测服务中心的实例列表和本地列表是否一致,不一致会发送告警,用户可以手工触发重新刷新SDK缓存。 (在CSE界面操作)2018-12-19 09:11:00.970|[Service Center Task]|ERROR|[InstanceCacheChecker.java:119]|instance cache not match. appId=AppGallerySearchService, microservice=AppGallerySearchService:AppGalleryMicroContentService.local cache: [{"instanceId":"0fa1021ff24911e888a800163e0b0521","serviceId":"0f95a43bf24911e888a800163e0b0521","endpoints":["rest://10.1.130.140:8087"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"JiuXianQiao"}},{"instanceId":"78aa5835035f11e9a9c100163e0b085a","serviceId":"789d2f4f035f11e9a9c100163e0b085a","endpoints":["rest://10.1.130.140:18080"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"RunZe"}}]remote cache: [{"instanceId":"78aa5835035f11e9a9c100163e0b085a","serviceId":"789d2f4f035f11e9a9c100163e0b085a","endpoints":["rest://10.1.130.140:18080"],"hostName":"ncn-hispace-govportal-1-130-140","status":"UP","properties":{},"healthCheck":{"mode":"push","port":0,"interval":30,"times":3,"ttl":120},"environment":null,"stage":null,"dataCenterInfo":{"name":"AppMarket","region":"North-China","availableZone":"RunZe"}}]这个功能可以帮助用户发现一些潜在问题,但是不是根本解决方案。 如果用户自己部署了服务中心,建议及时升级到最新版本, SDK也做好定期持续升级,避免老版本的BUG对业务产生影响。 
  • [教程] 【小链的烦恼】不想引入厚重的SDK,这里有你想要的REST API。快点来GET!
    扫码或者“点击这里”查看最新REST API Demo资料。
  • [技术干货] esdk-obs-java 扩展包
    本SDK是对华为OBS原生SDK(com.huawei.storage:esdk-obs-java)包装,在其基础上,提供断点上传、断点下载、回调、进度速率监控等特性。因此,本SDK不是原生SDK的替代,而是对原生SDK的补充。开发者应首先参考原生SDK的用户手册,在熟悉原生SDK的基础上再使用本SDK。下载链接:release一、功能1. 断点上传将整个上传任务转化为分段上传,每上传完一分段,在断点文件中记录完成分段上传结果,等所有分段上传成功后,合并所有分段。如果上传过程被中断,再次上传时,会读取断点文件中记录的分段结果,对于已经上传成功的分段不用再次上传。2.  断点下载将整个下载任务转化为分段(范围)下载,每个分段被成功的写入本地文件中后,在断点文件中记录完成分段结果,所有分段写入成功,即完成下载。如果下载过程被中断,再次下载时,会读取断点文件中记录的分段结果,对于已经成功的分段不用再次下载。3.  过程信息返回(进度,速率)在上传、下载操作中,对待上传的流/下载的流使用 ReadBytesMonitorInputStream 包装,其监控读取流的字节总数,并生成某一时刻的快照信息(包括总字节数、当前已读取字节数、当前时间、上一快照已读取字节数、上一快照时间等信息), 可以通过快照信息计算出进度、速率、是否完成等。二、日志配置参考原生SDK日志配置方式,如果要打印本SDK日志,配置logger name为"com.obs.extension"即可。注:当前SDK打印的日志级别为debug。<Logger name="com.obs.extension" level="debug" additivity="false">     <AppenderRef ref="NorthInterfaceLogAppender" /> </Logger>三、初始化该SDK提供了统一的对象操作门面,IObjectOperateClient。 要初始化 IObjectOperateClient ,需要传入原生SDK的obsClient实例,obsClient实例的初始化参考原生SDK手册。示例:IObjectOperateClient objectOperateClient = ObjectOperateClientImpl.newInstance(obsClient);四、代码示例1.  文件上传分段上传文件,支持断点续传和速率监控,IParallelUploadFuture 可以获取整个文件的速率信息,也可以获取每个分段上传的速率信息。//分段下载下载,开启断点续传和速率监控,关闭完整性校验 public void downloadFileWithProcessing() throws InterruptedException { String downloadFilePath = ""; String objectKey = ""; DownloadFileRequest request = new DownloadFileRequest(bucketName, objectKey); request.setDownloadFile(downloadFilePath); request.setEnableCheckpoint(true); request.setPartSize(5242880L); IParallelDownloadFuture downloadFuture = objectOperateClient.downloadFileAsyncWithProgress(request, false, printCallback); printProcessingInfo(downloadFuture.aggregationProcessing()); objectOperateClient.shutdown(); }2.  文件下载分段下载桶中对象到本地,支持断点续传、速率监控特性。//分段下载下载,开启断点续传和速率监控,关闭完整性校验 public void downloadFileWithProcessing() throws InterruptedException { String downloadFilePath = ""; String objectKey = ""; DownloadFileRequest request = new DownloadFileRequest(bucketName, objectKey); request.setDownloadFile(downloadFilePath); request.setEnableCheckpoint(true); request.setPartSize(5242880L); IParallelDownloadFuture downloadFuture = objectOperateClient.downloadFileAsyncWithProgress(request, false, printCallback); printProcessingInfo(downloadFuture.aggregationProcessing()); objectOperateClient.shutdown(); }3. printProcessingInfo() 方法public void printProcessingInfo(IProcessing processingInfo) throws InterruptedException { while (!processingInfo.isComplete()){ System.out.println("是否支持速率信息:" + processingInfo.isSupportProgress()); if(processingInfo.isSupportProgress()) { System.out.println("总字节数: " + processingInfo.getTotalBytes()); System.out.println("进度: " + processingInfo.getProgress()); } System.out.println("已传输: " + processingInfo.getTransferedBytes()); System.out.println("速率: " +processingInfo.perSecondRate() + " bytes/s"); System.out.println("-------------"); TimeUnit.MILLISECONDS.sleep(1000); } if (processingInfo.isComplete()) { System.out.println("是否支持速率信息:" + processingInfo.isSupportProgress()); if(processingInfo.isSupportProgress()) { System.out.println("总字节数: " + processingInfo.getTotalBytes()); System.out.println("进度: " + processingInfo.getProgress()); } System.out.println("已传输: " + processingInfo.getTransferedBytes()); System.out.println("速率: " +processingInfo.perSecondRate() + " bytes/s"); System.out.println("-------------"); } }
  • [技术干货] CSEJavaSDK连sc报错 404:Not Found, &quot;error_msg&quot;:&quot;API not exist or not published in the environment&quot;
    某些时候微服务注册到华为云CSE的时候,日志里面会打印错误内容2018-11-05 17:17:04.208  WARN 12692 --- [ntloop-thread-0] o.a.s.s.c.h.ServiceRegistryClientImpl    : get response for org.apache.servicecomb.serviceregistry.api.response.GetSchemasResponse failed, 404:Not Found, {"error_msg":"API not exist or not published in the environment","error_code":"APIGW.0101","request_id":"284c5c8b68ceed2411cbe958df208149"}这是由于microservice.yaml文件里面配置的连接服务中心、配置中心等的APIGateway地址还是旧域名https://cse.cn-north-1.myhwclouds.com,改成新的地址https://cse.cn-north-1.myhuaweicloud.com:443 就可以解决问题了。 PS:旧域名的APIGateway已经不更新了,并且预计以后会停止工作。推荐大家根据CSE或ServiceStage的CSE-SDK工具下载页面上发布的地址更新自己的配置
  • [技术干货] 使用CSE SDK在TCP、SSL握手过程中netty打印的日志如何关闭
    对于一些异常协议报文测试, CSE SDK 会打印大量的netty异常日志,比如:----TCP握手失败2018-09-03 14:13:31,843 [WARN ] [transport-vert.x-eventloop-thread-27][io.netty.util.internal.logging.Slf4JLogger.warn(Slf4JLogger.java:151)] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.java.io.IOException: Connection reset by peerat sun.nio.ch.FileDispatcherImpl.read0(Native Method)at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)at sun.nio.ch.IOUtil.read(IOUtil.java:192)at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)at java.lang.Thread.run(Thread.java:748)----SSL握手失败[2018-09-20 20:13:33,209/CST][transport-vert.x-eventloop-thread-4][WARN]An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. io.netty.util.internal.logging.Slf4JLogger.warn(Slf4JLogger.java:151)io.netty.handler.codec.DecoderException: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 474554202f20485454502f312e310d0a486f73743a203139322e3136382e302e3230343a383038320d0a436f6e6e656374696f6e3a206b6565702d616c6976650d0a43616368652d436f6e74726f6c3a206d61782d6167653d300d0a557067726164652d496e7365637572652d52657175657374733a20310d0a557365722d4167656e743a204d6f7a696c6c612f352e30202857696e646f7773204e542031302e303b20574f57363429204170706c65576at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)at io.netty.channel.AbstractChannelHandlerC可以通过:log4j.logger.io.netty.channel.DefaultChannelPipeline=ERROR,paas,stdout来关闭。 注意修改下后面的pass, stdout为自己的logger。关闭后,对于底层协议(TCP、SSL)可能没有任何错误信息。 会给定位带来麻烦。需要注意下。 新版本会做适当的优化,即即使给这个日志关闭,也打印少量的信息。
  • [技术干货] SDK如何设置超时时间?
    默认情况下SDK设置的超时时间是30秒,如果处理时间超过这个时间,则会打印超时日志,请求失败:2018-08-28 12:01:18,401 [ERROR] [transport-vert.x-eventloop-thread-14] [org.apache.servicecomb.transport.rest.client.http.RestClientInvocation.lambda$invoke$0(RestClientInvocation.java:97)] Failed to send request to /177.66.54.95:8443.java.util.concurrent.TimeoutException: The timeout period of 30000ms has been exceeded while executing PUT /rest/cbc/cbccustomerorgservice/v1/em/apply/apply-status for host 177.66.54.95当业务出现超时,并且是30s缺省设置的时候,应该尝试优化性能或者处理流程,已让系统更好的服务。比如设计流程,将超时操作作为后台任务运行,调用是立即返回的,然后通过状态查询接口来查询任务处理状态。不建议业务的接口处理时间超过10s以上,这样会设计到一系列性能问题。 当然,是开发测试阶段,可以通过下面的配置修改超时时间:servicecomb.rest.client.connection.idleTimeoutInSeconds: 30cse.request.timeout: 30000请求超时时间需要比IdelTimeout大一点
  • [视频点播] VOD SDK能做什么?
    简介媒体云点播服务软件开发工具包(VOD SDK,Video on Demand Software Development Kit)是对VOD服务提供的REST API进行的封装,以简化用户的开发工作。用户直接调用VOD SDK提供的接口函数即可实现使用VOD服务业务能力的目的。概述VOD SDK是对点播服务接口请求的封装,提供的接口包括创建媒资、确认媒资上传、媒资更新、媒资发布、媒资发布取消、查询媒资信息、修改媒资属性、删除媒资、媒资处理、CDN预热、创建媒资分类、修改媒资分类、删除媒资分类、查询分类及其子分类。请大家在使用SDK前务必先去查看点播服务的产品文档,了解相关接口的功能、参数、规则和使用方法。SDK工作流程除了点播服务SDK之外,用户还需集成其他SDK(如OBS SDK)。在创建媒资过程中用户与这几个SDK之间的配合如下:
总条数:806 到第
上滑加载中