-
项目是用spring boot2 开发的,现在集成cse, 用的是web方式,用项目里本身使用的jetty容器, 依赖里引入一下compile("org.apache.servicecomb:spring-boot2-starter-servlet:1.2.1")compile("com.huawei.paas.cse:cse-solution-service-engine:2.3.70")做了一些代码上的改造, 加了microservice.yaml , 在 intellij idea里可以正常运行, 但是打成jar包后在启动,发现问题,打印的日志:2019-07-24 13:29:59.887 - WARN 43428 --- [-thread-checker] io.vertx.core.impl.BlockedThreadChecker [line:51] : Thread Thread[vert.x-eventloop-thread-7,5,main] has been blocked for 4917 ms, time limit is 2000 ms2019-07-24 13:30:04.986 - WARN 43428 --- [-thread-checker] io.vertx.core.impl.BlockedThreadChecker [line:51] : Thread Thread[vert.xException in thread "qtp266273434-15" java.lang.OutOfMemoryError: MetaspaceException in thread "Thread-10" java.lang.OutOfMemoryError: Metaspace服务无法正常访问。 请问该怎么解决?
-
我看有些项目用的是servicecomb方式连接的CSE,那个包里有个类import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;,这个有个扩展,可以发送cse://格式消息但是我用的是spring-cloud,这个包需要怎样才能发送cse://这种消息,并且被cse接管,解析,转发呢现在用的是这个包注册到CSE的 cse-solution-spring-cloud
-
从我们目前已知的情况, CSE支持spring boot 1和spring boot 2的所有版本,缺省依赖的是1.5.12.RELEASE和2.0.0.RELEASE。 CSE和Spring Boot集成的原理可以参考: https://bbs.huaweicloud.com/blogs/eca98a6f399a11e9bd5a7ca23e93a891这里有和spring boot1和spring boot2的例子: spring boot 2: https://github.com/huaweicse/cse-java-chassis-samples/tree/master/porter spring boot 1: https://github.com/huaweicse/cse-java-chassis-samples/tree/master/springboot-samplespring boot1和spring boot2相关的pom依赖说明参考: https://huaweicse.github.io/cse-java-chassis-doc/using-cse-in-spring-boot/spring-boot-2.html
-
定义了如下接口: @GetMapping(path = "/v1/user111/ping", produces = MediaType.APPLICATION_JSON_VALUE) String ping111() { return null; }在Spring Boot下能够正常调用,切换CSE框架后,报告如下错误:o.a.s.c.rest.locator.OperationLocator : locate path failed, status:Not Found, http method:GET, path:/v1/user111/ping/, microserviceName:user-service出现这个原因是因为这个接口不是public的, CSE约束所有发布为接口的方法,必须是public,而spring boot则没这个限制。
-
在微服务架构中,客户端负载均衡是指负载均衡器作为客户端软件的一部分,客户端得到可用的服务实例列表然后按照特定的负载均衡策略,分发请求到不同的服务。ServiceComb内置了客户端负载均衡组件,开发者可以非常简单的使用。具体可参考:https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html 本文将介绍ServiceComb与SpringCloud的Ribbon负载均衡组件协同工作,以构建微服务应用。ServiceComb已适配对应的接口和配置,用户用极简单的方法配置后即可使微服务应用具备负载均衡的能力。示例以下通过一个服务提供者provider-service和消费者consumer-service作为demo演示。provider-service会启动3个微服务实例,消费者端consumer-service使用Ribbon负载均衡调用proveder-service服务的接口。其中consumer-service在调用provider-service提供的接口时会打印出真实调用的URL ↓↓↓完整示例地址:https://github.com/lisenwork/servicecomb-demo/tree/master/servicecomb-ribbon 预置条件: 示例应先安装启动服务与注册中心ServiceCenter,详细步骤请参考官网↓↓↓http://servicecomb.apache.org/cn/users/setup-environment/#%E8%BF%90%E8%A1%8Cservice-center 一开发服务消费者comsumer-service只需三步即可开发拥有负载均衡能力的微服务步骤如下:01添加依赖新建pom文件,引入如下依赖。完整pom文件内容请参考↓↓↓https://github.com/lisenwork/servicecomb-demo/blob/master/servicecomb-ribbon/consumer-service/pom.xml 02配置 在resources目录下新建ServiceComb配置文件microservice.yaml。配置微服务信息↓↓↓03项目入口新建启动类ConsumerApplication.java。如下图,启动类里同时实例化一个RestTemplate对象。该对象用于后面的服务间接口调用。新建ConsumerController.java。在该类的consumer方法里使用Ribbon的API动态获取服务实例,并打印出被选中的实例的真实IP地址和端口。最后调用服务实例的接口,获取结果并返回。04启动项目根目录下执行命令 mvn spring-boot:run二开发服务提供者provider-service01添加依赖新建pom文件,引入如下依赖。完整pom文件内容请参考↓↓↓https://github.com/lisenwork/servicecomb-demo/blob/master/servicecomb-ribbon/provider-service/pom.xml 02配置 在src/main/resources目录下新建microservice.yaml03项目入口新建启动类ProviderApplication.java新建ProviderController.java。只向外提供/provider接口04启动 服务提供者要启动3个微服务实例。打开microservice.yaml文件,分别修改微服务监听端口为8888,8889,8890,在项目根目录下执行3次命令 mvn spring-boot:run演示浏览器访问http://localhost:7777/consumer,重复刷新一定次数,观察控制台,会发现服务消费者会轮询调用服务提供者的三个实例。小结本文向社区读者从读者角度阐述了ServiceComb是如何支持SpringCloud Ribbon的。我们也非常欢迎爱好者们向社区提问和贡献代码。下章我们将介绍ServiceComb+SpringCloud Ribbon源码篇。如果在阅读代码时有任何疑问想交流,欢迎扫码加入进微信群。期待志同道合的朋友们加入ServiceComb的大门为你们敞开~用心做开源,不忘初衷前期阅读[学习微服务-第5天]ServiceComb+Zipkin源码解读[学习微服务-第4天]ServiceComb+Zipkin[学习微服务-第3天] ServiceComb内置高性能网关服务[每天学习微服务-源码解读] ServiceComb+SpringCloud Zuul[每天学习微服务-网关]ServiceComb+SpringCloud Zuul了解更多信息请访问官方网站http://servicecomb.apache.org/ Github代码仓库https://github.com/apache?q=ServiceComb
-
错误日志: java.lang.IllegalStateException: Another strategy was already registered. at com.netflix.hystrix.strategy.HystrixPlugins.registerCommandExecutionHook这个日志是由于spring boot也注册了hystrix,bizkeeper也会注册,hystrix不允许同时注册,但是又没接口能够判断是否已经注册(get方法有bug),所以会打印一个警告。 不影响功能。 如果没有bizkeeper的功能,可以在handler配置里面把他移除。 这样cse就不会尝试注册hystrix了,就没有这个异常了。 默认是这个,如果你们没定制的话:# 处理链配置 handler: chain: Provider: default: qps-flowcontrol-provider,bizkeeper-provider Consumer: default: qps-flowcontrol-consumer,loadbalance,fault-injection-consumer,bizkeeper-consumer修改为:# 处理链配置 handler: chain: Provider: default: qps-flowcontrol-provider Consumer: default: qps-flowcontrol-consumer,loadbalance,fault-injection-consumer当然也可以打个断点调试下registerCommandExecutionHook方法,看看spring boot 的哪个模块调用了这个方法。 如果不使用spring boot的功能不使用,去掉对应的jar包依赖也是可以的。
-
在微服务架构模式中后端服务的实例数一般是动态的,于客户端而言很难发现动态改变的服务实例的访问地址信息,服务网关能对用户提供统一的入口。 ServiceComb Java-Chassis 内置了网关服务EdgeService,开发者可以非常简单的搭建一个EdgeService服务。具体可参考:https://docs.servicecomb.io/java-chassis/zh_CN/edge/by-servicecomb-sdk.html 本文将介绍ServiceComb与SpringCloud的Zuul网关组件协同工作,以构建微服务应用。ServiceComb在自身的处理链HandlerTrain中已完成Zuul的对接,用户用极简单的方法配置后即可使微服务应用具备网关服务的能力。为使读者更好地理解,本文将编写一个简单的Hello微服务,并启动2个实例来进行演示。Hello微服务提供hello/{name}接口,只需从前端输入参数name就可从后端微服务获取到程序员百看不厌的Hello world结果。微服务模式下的Hello应用模型技术准备ServiceComb 作为后端微服务核心框架ServiceCenter 作为服务发现与注册中心SpringCloud Zuul 组件做服务网关环境准备以下环境为Windows 64位系统●安装git,详情可参考git安装教程https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git●安装JDK 1.8,详情可参考JDK安装教程。https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html●安装Maven 3.x,详情可参考Maven安装教程https://maven.apache.org/install.htmlServiceCenter安装下载地址:http://mirrors.hust.edu.cn/apache/servicecomb/servicecomb-service-center/1.1.0/下载后解压如下▼在该目录下双击service-center.exe即可启动,命令窗口中出现如下信息基本代表ServiceCenter启动成功,从这个信息也可以得知ServiceCenter监听的是30100端口,等下配置文件要用到。问题点:有可能会有如下信息,这个一般是端口被占用,很可能你打开了两个ServiceCenter,都关闭后再打开就可以了。↓↓↓示例一、后端微服务 HelloService01添加依赖新建maven项目HelloService,pom文件如下02配置新建ServiceComb配置文件src/main/resources/microservice.yaml,内容如下▼03项目入口新建启动类HelloApplication.java,内容如下▼新建Controller类HelloController.java (这里我习惯SpringMvc的叫法,重点看注解)04启动到此,Hello微服务就写完了。这里要启动2个实例。1.先打包,执行mvn clean package2.在项目根目录下target目录下将lib目录和生成的jar包复制到另一个目录中 3.复制jar包,修改其中一个jar包微服务启动端口号为8888(通过WinRar解压缩软件打开jar包并打开microservice.yaml文件修改里面的rest端口号) 4.在当前目录打开两个cmd命令窗口,分别执行命令java -jar HelloService-7777.jar和java -jar HelloService-8888.jar 。此时已经启动了2个微服务实例。二、编写Zuul网关服务01 添加依赖新建maven项目 zuulserver,pom文件如下02配置文件新建springboot配置文件src/main/resources/application.yaml,内容如下新建ServiceComb配置文件src/main/resources/microservice.yaml,内容如下03项目入口新建启动类 ZuulApplication.java新建静态文件 src/main/resources/static/index.html,内容如下 (static目录是按springboot项目规范,属于应用静态文件根目录)04启动到此,网关服务器写完,如下在IDEA里面直接启动应用三. 演示效果浏览器访问http://localhost:8080/ ,如下图。 在输入框中输入姓名,就可以在下面看到打招呼的信息连续点击几次打招呼按钮,可以在启动的2个Hello微服务实例的控制台中看到被调用的信息,如下图(由于这里使用的ServiceComb默认的负载均衡策略 轮询,可见到两个实例都均被调用,关于负载均衡,我们将在后续的文章中解读)。此时用户并不需要关心具体哪个实例被调用了,访问的是哪个后端的实例地址,它只要访问网关就可以了:)总结从以上的示例可以看出,通过 ServiceComb 结合SpringCloud Zuul 实现服务网关功能只需一些简单的配置。后续可以在网关服务上实现统一的鉴权,日志记录,和自定义过滤器等。参考[1] SpringCloud Zuulhttps://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html [2] ServiceCombhttp://servicecomb.apache.org/cn/docs/quick-start/
-
2019-01-18 17:12:48.711 ERROR 9456 --- [ntloop-thread-0] o.a.s.config.client.ConfigCenterClient : Config update from https://cse.cn-north-1.myhuaweicloud.com failed.2019-01-18 17:12:48.711 ERROR 9456 --- [ntloop-thread-0] o.a.s.config.client.ConfigCenterClient : Server error message is [{"error_code":"SVCSTG.CSE.400607","error_message":"According to the value of 'mutidimen.configKeyFormat', dimensionsInfo ('${spring.application.name}@houseapp#0.0.1') shouldn't have special char '[$, %, ^, &, +, /, , \\]'"}].这个错误是由于微服务名称错误。 从日志看出,微服务名称是 ${spring.application.name} ,这个是一个place holer。 需要制定这个配置项的值。
-
Q:用Postman测试接口可以调通过,swagger-ui页面测试我的接口经常出现connect: connection timed out.A:确认下frontend跟你的应用网络是否通,servicecomb的swagger-ui现在是proxy模式,不是直连Q:准备使用servercomb,下载了center和demo项目,demo项目一直提示ERROR 9868 --- [ntloop-thread-0] o.a.s.s.client.http.RestUtils ......message: Connection timed out求指点A:1.httpaddr/httpport of your service center conf2.service registry address in your microservice.yamlQ:restschema与rpcschema两种方式在性能上有区别吗?A:@RestSchema 注解用于 SpringMVC 和 JAX-RS 两种服务开发风格,而 @RpcSchema 注解用于透明RPC开发风格,这两种注解的差异主要体现在服务端代码开发风格和契约生成模式上。Java-Chassis有一个隐式契约功能,可以让框架根据服务端接口代码自动生成服务契约。由于 SpringMVC 和 JAX-RS 开发风格会在REST接口上打上各种注解,有利于框架生成更符合REST风格的契约;而透明RPC模式由于接口上没有注解,Java-Chassis框架无法确定接口语义以及各个参数在HTTP请求中的位置,因此所有的接口都会作为 POST 接口处理,请求参数都会包装到HTTP请求的body中。这样的契约不太符合REST风格。因此,Java-Chassis更推荐用户使用 @RestSchema 注解开发服务端接口,这样用户只需要写代码,就能让框架自动生成符合REST风格的服务契约。Java-Chassis的传输模型和编程模型是解耦合的。传输模型方面,Java-Chassis支持REST和highway,其中REST又分为以Vert.x作为底层通信框架的REST over Vertx和以Tomcat之类的servlet容器为底层通信框架的REST over Servlet。Java-Chassis的性能主要受传输模型的影响。当用户选择了一个确定的传输模型后,无论他在服务端选择的是哪种编程模型性能都是差不多的。最后,Java-Chassis在客户端代码开发风格上提供了RPC开发模式和RestTemplate开发模式,在其他条件完全相同的情况下,RPC开发模式的性能比RestTemplate高,因此更推荐使用RPC模式编写consumer端代码。http://zhibo.huaweicloud.com/?referVisitorId=oiOYo0XLXIVOMO-ACc9q2cKXGOFQ&c=activity&a=live&id=151108&from=timeline&isappinstalled=0这里视频有说明性能比较数据Q:Caused by: java.lang.IllegalStateException: The schema(id=[calculatorRestEndpoint]) content held by this instance and the service center is different. You need to increment microservice version before deploying. Or you can configure service_description.environment=development to work in development environment and ignore this error 在bmi例子上做修改,报上面这个错,怎么解决啊?A:这通常是因为你修改了REST接口定义,但是既没有升级微服务版本号,也没有把环境配置成开发环境,所以ServiceComb启动实例检查契约的时候发现契约内容不一致,就报错了。可以考虑升级一下微服务版本号,或者在microservice.yaml文件里面配置一下service_description.environment=development,或者等sc里面的服务实例下线后,把微服务信息删掉重新注册。Q:有谁知道吗?除了注解方式@RequestHeader,还有什么方法可以在Controller中拿到request中的header参数?目前测试发现HttpServletRequest没法拿到A:如果这个Header参数定义在了你的接口契约里,那你的REST接口方法能直接拿到header参数。否则可以扩展一个HttpServerFilter从requestEx参数里面拿header,也可以在你的REST接口里面加上HttpServletRequest参数,从里面拿到headerQ:如何将一个服务部署多个,实现自动减压的?是在配置文件上设置,还是使用其他工具实现。给个链接谢谢。A:https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.htmlQ:The Service pv-web's instance 62d30daeed5011e8af2f00e081ba3ef7 has been isolated for a while, give a single test opportunity. org.apache.servicecomb.loadbalance.filter.IsolationDiscoveryFilter.allowVisit(IsolationDiscoveryFilter.java:119)?A:你贴出来的日志表示pv-web服务的某个实例被隔离了,现在已经经过了一段时间,Java-Chassis框架在尝试将一个请求路由到该实例,看看它能否被调通,如果调通了的话,这个实例就会从隔离状态恢复过来。https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html 请参考这篇文档的“实例隔离功能”。Q:启动ServiceComb-java-chassis项目 sample/codefirst-sample 目录里的 CodeFirstProviderMain,例子程序怎么启动不起来?Caused by: java.lang.NoSuchMethodError: org.apache.commons.lang3.reflect.MethodUtils.getMethodsWithAnnotation(Ljava/lang/Class;Ljava/lang/Class;ZZ)[Ljava/lang/reflect/Method; at org.apache.servicecomb.foundation.common.event.SimpleEventBus.collectSubscribers(SimpleEventBus.java:41) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) at org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx.computeIfAbsent(ConcurrentHashMapEx.java:56) at org.apache.servicecomb.foundation.common.event.SimpleEventBus.register(SimpleEventBus.java:51) at org.apache.servicecomb.serviceregistry.task.AbstractTask.<init>(AbstractTask.java:38) at org.apache.servicecomb.serviceregistry.task.AbstractRegisterTask.<init>(AbstractRegisterTask.java:28) at org.apache.servicecomb.serviceregistry.task.MicroserviceRegisterTask.<init>(MicroserviceRegisterTask.java:47) at org.apache.servicecomb.serviceregistry.task.MicroserviceServiceCenterTask.<init>(MicroserviceServiceCenterTask.java:28) at org.apache.servicecomb.serviceregistry.registry.AbstractServiceRegistry.createServiceCenterTask(AbstractServiceRegistry.java:201) at org.apache.servicecomb.serviceregistry.registry.AbstractServiceRegistry.init(AbstractServiceRegistry.java:106) at org.apache.servicecomb.serviceregistry.registry.RemoteServiceRegistry.init(RemoteServiceRegistry.java:54) at org.apache.servicecomb.serviceregistry.RegistryUtils.init(RegistryUtils.java:66) at org.apache.servicecomb.core.CseApplicationListener.setApplicationContext(CseApplicationListener.java:48) at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:121) at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:97) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1622) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.d**ateBean(AbstractAutowireCapableBeanFactory.java:555) ... 13 moreA:用户本地工程的lang3包没有更新到ServiceComb配套的版本,解决方法:1.在用户本地工程的pom.xml点击鼠标右键,选择执行 maven -> reimport2.在用户本地工程的pom.xml点击鼠标右键,选择执行 maven -> Show effective pom,确认其中的lang3是:<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.6</version> </dependency>Q:ServiceComb配置中心支持“配置更新后自动刷新到服务”,如果服务有多个节点,是如何实现的?想来如果是API调用刷新不能确定刷到每个节点,是否cse client端有消息流和配置中心连接呢?类似于企业总线。如果是消息总线,那么业务服务里,需要配置消息总线的url等信息吗? A:微服务需要配置中心地址。定期pull配置,或者建立websocket链接采用push机制Q:在 ServiceComb-CRM-WorkShop 例子中 边缘服务afterReceiveRequest方法 在调用String userName = template.getForObject("cse://"+USER_SERVICE_NAME + "/validate?token={token}", String.class, token)时候,第一次调用正常后边调用会出现阻塞线程问题,报错:Thread Thread[transport-vert.x-eventloop-thread-4,5,main] has been blocked for 5433 ms, time limit is 2000A:ServiceComb的Edge Service默认工作于高性能的reactive模式,此模式要求工作于Edge Service转发流程中的业务代码不能有任何的阻塞操作。该问题是由于用户业务模型无法满足reactive要求,因此,可以通过修改微服务的配置文件,使用ServiceComb提供的同步线程池模式解决。使用指南可以参考:https://docs.servicecomb.io/java-chassis/zh_CN/edge/by-servicecomb-sdk.htmlQ:spring mvc项目中实现的filter,切换到微服务后,全部不起作用了,是不支持springmvc里边的filter了吗?用户工程同时添加了springboot和provider-springmvc的依赖:<dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <!-- springmvc支持 --> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-springmvc</artifactId> </dependency>A:问题原因是因为springmvc和ServiceComb REST是两套不同架构,用户将基于springmvc的项目切换到ServiceComb后,还需要基于ServiceComb REST规则对老的filter做微调,ServiceComb提供相关的架构迁移案例,详情可以参考:1.不同框架之间迁移改造可能工作量的评估指南:https://bbs.huaweicloud.com/blogs/ba7b62178cb811e89fc57ca23e93a89f 可以参考下2.在Spring Boot中使用ServiceComb:https://huaweicse.github.io/cse-java-chassis-doc/using-cse-in-spring-boot/using-cse-in-spring-boot.htmlQ:ServiceComb支持thymeleaf吗?A:这个是个web框架,需要在web容器里面运行,其实和servicecomb是两个完全独立的东西了。servicecomb也支持在web容器里面运行,理论上两个都可以放到一起跑,但我们没用过这个框架。 https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/protocol/rest-over-servlet.htmlQ:原来的那些过滤器都失效了,怎么做才可以既保持原有的能力,又可以把需要发布的接口通过@RestSchema申明出去?A:因为是两个不同的运行时,涉及到“框架内部机制”,而不仅仅是“形式”上的东西。 结合功能,一般都有对应的解决方案的。附上一个简单的不同框架之间迁移改造可能工作量的评估指南: https://bbs.huaweicloud.com/blogs/ba7b62178cb811e89fc57ca23e93a89f 可以参考。 Q:群里有人压过 servicecomb 同步restful 和 spring boot的restful的差距吗?A:网上有很多对比分析,我们也有测试过。一般标准的虚拟机4u8g,差不多分别是5万单位和1万单位。servicecomb restful和其它rpc框架,比如grpc,dubbo,tars等在一个差不多的水准,即5万单位。和调优方式,测试方法不同,会有一些偏差。Q:蓝云上安装了mysql,启动alpha的jar包,直接跑saga源码里的saga-servicecomb-demo,能成功体验事务,照着saga源码里的saga-servicecomb-demo写了个一模一样的工程,是springboot接入servicecomb,调用却出了问题,子事务那边报空指针异常,globalTxId,parentTxId都为null, localTxId有值;自己没找出原因,谁了解这块的帮个忙看下吧,代码地址是:https://github.com/weichao666/sagademoA:saga demo的那个问题解决了,如果使用java chassis1.0.0版本,需要引入guava20.0版本,否则启动报错,注解和调用链正确配置的情况下,使用java chassis1.1.0-SNAPSHOT版本是没问题的,java chassis1.0.0版本使用的guava是19.0Q:ServiceComb中的同步 restful 需要特殊配置吗?A:除edge service之外,ServiceComb的restful默认都是同步的,不需要特殊配置。今天的FAQ精选问题总计20个,可以手动收藏一下哦~And小蜜蜂欢迎来我们社区提问笔芯关注我们~
-
本帖最后由 木头羊 于 2018-5-30 12:54 编辑如果使用最基本的服务发布的能力,ServiceComb的最小依赖是哪些? 我们项目比较老,希望保持现有的Spring 3.x依赖不动,新增接口通过REST方式注册到service center, 我看到ServiceComb依赖的Spring版本都是4.x+,不知能否基于Spring 3.x版本进行微服务改造?
-
RT
-
Q: ServiceComb日志替换A: CSE java-chassis日志推荐方式是在启动的时候使用Log4jUtils.init(),直接使用推荐的Log4j来做日志管理,但是有些场景不想用log4j,比如想使用log4j2或者logback,下面以log4j2为例简单介绍下步骤:在代码里面不要使用Log4jUtils.init();去掉log4j的配置文件(不删掉也没关系,因为不会使用);exclude掉CSE框架引入的log4j,例如:<dependency> <groupId>io.servicecomb</groupId> <artifactId>provider-springmvc</artifactId> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> Copy引入log4j2的依赖<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> Copy如果没有版本依赖管理,还需要填写上版本号。加入log4j2的配置文件log4j2.xml,关于这个请查看官方说明,例如: <?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> <configuration status="WARN" monitorInterval="30"> <!--先定义所有的appender--> <appenders> <!--这个输出控制台的配置--> <console name="Console" target="SYSTEM_OUT"> <!--输出日志的格式--> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> </console> <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用--> <File name="log" fileName="log/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> <DefaultRolloverStrategy max="20"/> </RollingFile> <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> <logger name="org.springframework" level="INFO"></logger> <logger name="org.mybatis" level="INFO"></logger> <root level="all"> <appender-ref ref="Console"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> </loggers> </configuration> Copy启动服务进行验证Q: netty版本问题A: netty3和netty4是完全不同的三方件,因为坐标跟package都不相同,所以可以共存,但是要注意小版本问题,小版本必须使用CSE的版本。Q: 服务超时设置A: 在微服务描述文件(microservice.yaml)中添加如下配置: cse: request: timeout: 30000 CopyQ: URL 地址就可以唯一定位,为什么要加上一个schema?A:schema 是用来匹配服务契约的,用来保证服务端和消费端契约兼容,每个契约需要一个唯一ID,在服务中心存储。schema映射到java的inte**ce概念,在consumer使用透明rpc模式开发时,可以找到是微服务里的哪个operation。schema之间的方法名是没有唯一性要求的。operation qualified name是治理的key,而URL 因为path参数的存在,没办法直接查找,而qualified name是不会变的。治理是不区分传输的,如果治理按URL 走,那么highway调进来时,还得根据参数反向构造出url,再来正则表达式匹配,太折腾了。http只是一种传输通道,还有别的传输通道不需要映射到URL的。Q: rest客户端调用的时候,实际上只带上了服务名和URL,并不需要指定schema id的, 而实际上根据这个URL也能找到具体契约的,所以指定schema id作用何在?A: 由于透明rpc是接口式调用,并没有URL,内部实际都归一化到operation来描述的,这样就可以结合schema id唯一定位到具体的请求处理中。Q: Transport是个什么概念?用来干什么的?A: transport负责编解码,以及传输。通信模型有rest和highway两种,highway对应的是私有协议,使用protobuf编码,rest用的是json。hightway和rest都是基于vertx做的,vertx是基于netty的。Q: 框架中引入了vertx会有什么好处?A: 启用vertx的标准工作模式更强大,不过对业务人员要求就有些高了,目前还没开放业务接口出来。vertx标准的reactive工作模式,要求业务代码中不能有任何的block wait,sleep,大循环,总之,不能停下来。做到这一点,可以用少很多的CPU,提供更多的服务。Q: 一个服务提供者里面会有多个 appid 和微服务吗?什么场景会出现这种情况?A: 会,这里表达的是一个merge的概念。microservice.yaml文件,可能同时存在于jar,磁盘,命令行参数指定这几个地方,此时他们按优先级合并,是用于增加灵活性的。在jar里的是默认值,在此之外,还有环境变量,命令行参数,配置中心覆盖,提供多层定制。Q: ServiceComb和服务中心是怎么交互的?A: 走rest,主要负责注册,取数据和心跳等;watch事件走websocket,watch事件是观察服务中心实例信息有没有变更。Q: 有类似dubbo那种治理中心吗?A: bizkeeper是一个handler,是治理的其中一个内容。治理可以通过handler扩展。Q: service path怎么理解?A: 每个微服务有一个servicePathManager,每一个schema将自己的path注册进去。Q: 这样浏览器能访问到吗?A: 可以,restful的URL路由,都是由service path搞定。Q: 契约生成时,需要强制带上版本号和语言吗?A: 契约是属于微服务的,微服务本来就有版本,但语言是不应该带上版本号的。应该契约要求与语言无关。契约“没有版本”,契约的版本体现在微服务上,实例能找到所属的微服务的版本,就能找到一个确定的契约。Q: ServiceRegistry里的设计代码和Eureka很类似?A: 我们第一个版本就是在Spring Cloud的基础上做的 后来随着发展发现不够用了才逐渐自己做的一套,所以的确是在充分参考Eureka后设计的。Q: 有些rpc是netty调用redis实现,比直接netty转发优势在哪里?A: 可能是想用redis解决订阅发布吧。但这样意义也不大,之前也尝试过这么用,但后来都改成ServiceComb了。Q: 如果同时引入了transport-rest-servlet和transport-rest-vertx的依赖,那么它怎么决定采用哪一个?A: 如果端口没被占用,就用vertx;如果被占用了,就用servlet。Q: qps流控设计时是出于什么场景考虑的?A: 限流有两个主要作用,第一通过给不同的消费者限流保证对一些重点服务的服务效果,第二防止雪崩效应。可根据服务的重要性来决定水管的粗细,ServiceComb是支持消费端限流和服务端限流两种限流方式的,消费端限流可以做到比较精细的控制。Q: 如果服务端是链式调用,即类似a->b->c,那设置了qps 流控会不会造成水管粗细不均的事情?A: 一般采取的模式是先测量再设置。qps设置最终是结合整体业务需求来进行调控的,而不是就单个节点来进行设置。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签