• [热门活动] 【云原生专题直播有奖提问】DTSE Tech Talk 技术直播 NO.46:看直播提问题赢华为云定制保温杯、华为云定制POLO衫等好礼!
    中奖结果公示感谢各位小伙伴参与本次活动,本次活动因问题均与直播间中问题重复,无符合要求内容,故本期无中奖人员。直播简介【直播主题】云原生微服务的下一站:Proxyless Service Mesh【直播时间】2023年10月25日 16:30-18:00【直播专家】杨奕 华为云云原生DTSE技术布道师 李来 华为云云原生DTSE技术布道师【直播简介】云原生微服务治理技术的下一代演进方向是什么?Proxyless Service Mesh! 本期直播讲聚焦于云原生微服务治理技术,介绍了从SOA、微服务SDK到Service Mesh、Proxyless Service Mesh的演进历程,并演示如何基于开源的云原生无代理服务网格Sermant,帮助用户以零代码修改的方式来将SOA架构应用向Proxyless Service Mesh架构进行改造,实现微服务架构的平滑演进和升级。直播链接:cid:link_0活动介绍【互动方式】直播前您可以在本帖留下您疑惑的问题,专家会在直播时为您解答。直播后您可以继续在本帖留言,与专家互动交流。我们会在全部活动结束后对参与互动的用户进行评选。【活动时间】即日起—2023年10月26日【奖励说明】评奖规则:活动1:直播期间在直播间提出与直播内容相关的问题,对专家评选为优质问题的开发者进行奖励。奖品:华为云定制保温杯活动2:在本帖提出与直播内容相关的问题,由专家在所有互动贴中选出最优问题贴的开发者进行奖励。奖品:华为云定制POLO衫更多直播活动直播互动有礼:官网直播间发口令“华为云 DTSE”抽华为云定制飞盘、填写问卷抽华为云定制长袖卫衣等好礼分享问卷有礼 :邀请5位朋友以上完成问卷即可获得华为云定制帆布袋。老观众专属福利:连续报名并观看DTT直播3期以上抽送华为云DTT定制T恤。【注意事项】1、所有参与活动的问题,如发现为复用他人内容或直播间中重复内容,则取消获奖资格。2、为保证您顺利领取活动奖品,请您在活动公示奖项后2个工作日内私信提前填写奖品收货信息,如您没有填写,视为自动放弃奖励。3、活动奖项公示时间截止2023年10月27日,如未反馈邮寄信息视为弃奖。本次活动奖品将于奖项公示后30个工作日内统一发出,请您耐心等待。4、活动期间同类子活动每个ID(同一姓名/电话/收货地址)只能获奖一次,若重复则中奖资格顺延至下一位合格开发者,仅一次顺延。5、如活动奖品出现没有库存的情况,华为云工作人员将会替换等价值的奖品,获奖者不同意此规则视为放弃奖品。6、其他事宜请参考【华为云社区常规活动规则】。
  • [技术干货] 微服务|SpringBoot 3.0 新特性实测——内置声明式HTTP客户端-转载
     声明式HTTP接口 声明式 http 客户端主旨是使得编写 java http 客户端更容易。为了贯彻这个理念,采用了通过处理注解来自动生成请求的方式(官方称呼为声明式、模板化)。通过声明式 http 客户端实现我们就可以在 java 中像调用一个本地方法一样完成一次 http 请求,大大减少了编码成本,同时提高了代码可读性。  举个例子,如果想调用 /tenants 的接口,只需要定义如下的接口类即可  public interface TenantClient {    @GetExchange("/tenants")   Flux<User> getAll(); } 1 2 3 4 5 Spring 会在运行时提供接口的调用的具体实现,如上请求我们可以如 Java 方法一样调用  @Autowired TenantClient tenantClient;  tenantClient.getAll().subscribe(  ); 1 2 3 4 5 6 如果我们想使用HTTP GET /users API,那么我们可以简单地编写:  public interface UserClient {   @GetExchange("/users")   Flux<User> getAll(); } 1 2 3 4 Spring会在运行时提供接口和exchange实现,我们只需要调用getAll()方法。  @Autowired UserClient userClient; userClient.getAll().subscribe(     data -> log.info("User: {}", data) ); 1 2 3 4 5 测试使用 1. Maven 声明式HTTP接口功能是spring-web依赖的一部分,当我们引入spring-boot-starter-web或spring-boot-starter-webflux时,它就会被传递引入。如果我们想添加响应式支持,那么就包括后面的依赖。  <dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-web</artifactId> </dependency>  <!-- For reactive support --> <dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-webflux</artifactId> </dependency> 1 2 3 4 5 6 7 8 9 10  2.创建HTTP服务接口 在Spring中,HTTP服务接口是一个带有@HttpExchange方法的Java接口。带注释的方法被视为HTTP端点,细节通过注解属性和输入法参数类型静态定义。 交流的方法 我们可以使用以下注解将方法标记为HTTP服务端点:  @HttpExchange:是指定HTTP端点的通用注释。当在接口级别使用时,它适用于所有方法。 @GetExchange:为HTTP GET请求指定@HttpExchange。 @PostExchange:对于HTTP POST请求,指定@HttpExchange。 @PutExchange:为HTTP PUT请求指定@HttpExchange。 @DeleteExchange:对于HTTP DELETE请求,指定@HttpExchange。 @PatchExchange:对于HTTP Patch请求,指定@HttpExchange。 1 2 3 4 5 6 方法参数 exchange方法在方法签名中支持下列方法参数:  URI:设置请求的URL。 @PathVariable:将请求URL中的值替换为占位符。 @RequestBody:提供请求的主体。 @RequestParam:添加请求参数。当“content-type”设置为“application/x-www-form-urlencoded”时,请求参数会在请求体中编码。否则,它们将作为URL查询参数添加。 @ requesttheader:添加请求头的名称和值。 @RequestPart:可用于添加请求部分(表单字段,资源或HttpEntity等)。 @CookieValue:向请求中添加cookie。 1 2 3 4 5 6 7 示例代码:  @PutExchange void update(@PathVariable Long id, @RequestBody User user); 1 2 返回值 HTTP exchange方法可以返回如下值:  阻塞或反应性(Mono/Flux)。 只有特定的响应信息,如状态码和/或响应头。 Void,表示该方法仅被视为execute方法; 1 2 3 对于阻塞交换方法,我们通常应该返回ResponseEntity,而对于响应式方法,我们可以返回Mono/Flux类型。  //阻塞性 @GetExchange("/{id}") User getById(...);  //Reactive @GetExchange("/{id}") Mono<User> getById(...); 1 2 3 4 5 6 7 3.构建HttpServiceProxyFactory HttpServiceProxyFactory是一个从HTTP服务接口创建客户端代理的工厂。使用它的HttpServiceProxyFactory.builder(client).build()方法来获取代理bean的实例。  import com.fasterxml.jackson.databind.ObjectMapper; import com.leftso.app.web.UserClient; import lombok.SneakyThrows; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.support.WebClientAdapter; import org.springframework.web.service.invoker.HttpServiceProxyFactory;  @Configuration public class WebConfig {   @Bean   WebClient webClient(ObjectMapper objectMapper) {     return WebClient.builder()         .baseUrl("https://jsonplaceholder.typicode.com/")         .build();   }   @SneakyThrows   @Bean   UserClient postClient(WebClient webClient) {     HttpServiceProxyFactory httpServiceProxyFactory =         HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient))             .build();     return httpServiceProxyFactory.createClient(UserClient.class);   } }  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 注意,我们已经在WebClient bean中设置了远程API的基础URL,因此我们只需要在交换方法中使用相对路径。  4. HTTP业务接口示例 下面是与https://jsonplaceholder.typicode.com/users/端点交互并执行各种操作的HTTP接口示例。  import com.leftso.app.model.User; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.service.annotation.DeleteExchange; import org.springframework.web.service.annotation.GetExchange; import org.springframework.web.service.annotation.HttpExchange; import org.springframework.web.service.annotation.PostExchange; import org.springframework.web.service.annotation.PutExchange; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono;  @HttpExchange(url = "/users", accept = "application/json", contentType = "application/json") public interface UserClient {   @GetExchange("/")   Flux<User> getAll();    @GetExchange("/{id}")   Mono<User> getById(@PathVariable("id") Long id);    @PostExchange("/")   Mono<ResponseEntity<Void>> save(@RequestBody User user);    @PutExchange("/{id}")   Mono<ResponseEntity<Void>> update(@PathVariable Long id, @RequestBody User user);    @DeleteExchange("/{id}")   Mono<ResponseEntity<Void>> delete(@PathVariable Long id); }  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 注意,我们创建了一个User类型的记录来保存用户信息。  public record User(Long id, String name, String username, String email) {} 1 现在我们可以将UserClient bean注入到应用程序类中,并调用方法以获取API响应。  @Autowired UserClient userClient; //获取所有用户 userClient.getAll().subscribe(     data -> log.info("User: {}", data) ); //通过id获取用户 userClient.getById(1L).subscribe(     data -> log.info("User: {}", data) ); //创建一个新用户 userClient.save(new User(null, "Lokesh", "lokesh", "admin@email.com"))     .subscribe(         data -> log.info("User: {}", data)     ); //通过id删除用户 userClient.delete(1L).subscribe(     data -> log.info("User: {}", data) );  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 总结 在这个Spring(Spring Boot 3.0)教程中,我们通过示例学习了如何创建和使用声明式HTTP客户端接口。  Spring Boot3.0王炸版本带来了很多新特性,值得我们深入学习,推荐给大家哔站上讲解细致且全面的springboot3教程,全方面详解了SpringBoot核心知识点,采用了知识点配合项目案例的方式,可以让大家很轻松的掌握SpringBoot,配套资料也非常全面,领取方式可看视频简介区~ ———————————————— 版权声明:本文为CSDN博主「陈橘又青」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_63947499/article/details/131812612 
  • [技术干货] 服务部署-单实例单节点
    定义Single Service Instance per Host(单实例单节点)是一种常用的微服务部署模式,微服务的一个实例独立部署在一台主机之上,实例独占该主机运行。该模式有两种变体:Single Service Instance per VM(单实例单虚拟机)Single Service Instance per Container(单实例单容器)。单实例单虚拟机部署将服务打包为VM镜像,每个服务实例都是使用该镜像启动的VM实例。单实例单容器部署将服务打包为容器镜像,并将服务实例以容器的方式部署。两种变体的差别单实例单虚拟机需要为每个应用程序分配一个完整的虚拟机,这会导致资源浪费和额外的管理成本。而单实例单容器可以在同一个虚拟机中运行多个应用程序,共享资源,提高资源利用率。此外,容器可以更快速地启动和停止,更容易管理和部署。因此,单实例单容器更适合现代化的应用程序部署和管理。单实例部署优缺点优点单实例单容器是一种部署架构,它将一个应用程序实例部署在一个容器中。这种架构有以下几个优点:简化部署和管理:单实例单容器使得应用程序的部署和管理变得更加简单和可靠。因为每个容器只运行一个实例,所以容器的配置和管理都变得更加容易。提高可靠性和稳定性:单实例单容器使得应用程序更加可靠和稳定。因为每个容器只运行一个实例,所以容器之间的隔离性更强,一个容器出现问题不会影响其他容器的运行。提高资源利用率:单实例单容器可以更好地利用资源。因为每个容器只运行一个实例,所以它们可以共享同一个主机的资源,避免资源浪费。更好的扩展性:单实例单容器使得应用程序更容易扩展。因为每个容器只运行一个实例,所以可以根据需要增加容器的数量来扩展应用程序的能力。缺点单实例单容器也有一些缺点,主要包括以下几点:单点故障:由于每个容器只运行一个实例,所以如果该实例出现故障,整个应用程序就会崩溃。这种情况下,需要手动重启容器或者使用自动化工具来进行容器的恢复。资源限制:单实例单容器的资源是有限的,因为每个容器只能运行一个实例。如果应用程序需要更多的资源,需要增加容器的数量,这样可能会导致资源的浪费。部署复杂性:单实例单容器的部署需要手动完成,这可能会增加部署的复杂性和时间成本。如果需要部署多个容器,需要手动配置和管理每个容器,这可能会增加管理的工作量。不适合大规模应用程序:单实例单容器适合小规模应用程序,但对于大规模应用程序来说,需要更复杂的部署架构来保证高可用性和可扩展性。微服务和单体应用各自的应用场景微服务和单体应用都有各自的优缺点和适用场景。当应用程序较小,功能简单,不需要大量的扩展和升级时,使用单体应用是一种较为简单和快速的解决方案。当应用程序较大,功能复杂,需要大量的扩展和升级时,使用微服务可以更好地实现应用程序的模块化和分布式部署,提高应用程序的可伸缩性和可靠性。此外,微服务还可以更好地支持多语言和多技术栈的混合开发,使得团队可以选择最适合自己的技术栈进行开发。总之,当应用程序的规模和复杂度较大时,使用微服务可以更好地满足需求,而当应用程序较小且功能简单时,使用单体应用是一种更为简单和快速的解决方案。
  • [分享交流] 各位大佬们最近有在找工作的吗?行情咋样啊
    各位大佬们最近有在找工作的吗?行情咋样啊,想先了解一下情况。
  • [技术干货] 微服务Spring Boot 整合 Redis 实现 好友关注-转载
    一、Redis 实现好友关注 – 关注与取消关注需求:针对用户的操作,可以对用户进行关注和取消关注功能。在探店图文的详情页面中,可以关注发布笔记的作者具体实现思路:基于该表数据结构,实现2个接口关注和取关接口判断是否关注的接口关注是用户之间的关系,是博主与粉丝的关系,数据表如下:tb_followCREATE TABLE `tb_follow` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`user_id` bigint(20) unsigned NOT NULL COMMENT '用户id',`follow_user_id` bigint(20) unsigned NOT NULL COMMENT '关联的用户id',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;id为自增长,简化开发核心代码FollowController//关注@PutMapping("/{id}/{isFollow}")public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFollow) {return followService.follow(followUserId, isFollow);}//取消关注@GetMapping("/or/not/{id}")public Result isFollow(@PathVariable("id") Long followUserId) {return followService.isFollow(followUserId);}FollowService@Overridepublic Result follow(Long followUserId, Boolean isFollow) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 1.判断到底是关注还是取关if (isFollow) {// 2.关注,新增数据Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean isSuccess = save(follow);if (isSuccess) {stringRedisTemplate.opsForSet().add(key, followUserId.toString());}} else {// 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?boolean isSuccess = remove(new QueryWrapper().eq("user_id", userId).eq("follow_user_id", followUserId));if (isSuccess) {// 把关注用户的id从Redis集合中移除stringRedisTemplate.opsForSet().remove(key, followUserId.toString());}}return Result.ok();}@Overridepublic Result isFollow(Long followUserId) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();// 2.查询是否关注 select count(*) from tb_follow where user_id = ? and follow_user_id = ?Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();// 3.判断return Result.ok(count > 0);}代码编写完毕,进行测试代码测试点击进行关注用户关注成功取消关注测试成功二、Redis 实现好友关注 – 共同关注功能实现共同关注好友功能,首先,需要进入博主发布的指定笔记页,然后点击博主的头像去查看详细信息核心代码如下UserController// UserController 根据id查询用户@GetMapping("/{id}")public Result queryUserById(@PathVariable("id") Long userId){// 查询详情User user = userService.getById(userId);if (user == null) {return Result.ok();}UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);// 返回return Result.ok(userDTO);}BlogController@GetMapping("/of/user")public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current,@RequestParam("id") Long id) {// 根据用户查询Page page = blogService.query().eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 获取当前页数据List records = page.getRecords();return Result.ok(records);}那么如何实现共同好友关注功能呢?需求:利用Redis中的数据结构,实现共同关注功能。 在博主个人页面展示出当前用户与博主的共同关注思路分析: 使用Redis的Set集合实现,我们把两人关注的人分别放入到一个Set集合中,然后再通过API去查看两个Set集合中的交集数据改造核心代码:当用户关注某位用户后,需要将数据存入Redis集合中,方便后续进行共同关注的实现,同时取消关注时,需要删除Redis中的集合FlowServiceImpl@Overridepublic Result follow(Long followUserId, Boolean isFollow) {// 1.获取登录用户Long userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 1.判断到底是关注还是取关if (isFollow) {// 2.关注,新增数据Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean isSuccess = save(follow);if (isSuccess) {stringRedisTemplate.opsForSet().add(key, followUserId.toString());}} else {// 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?boolean isSuccess = remove(new QueryWrapper().eq("user_id", userId).eq("follow_user_id", followUserId));if (isSuccess) {// 把关注用户的id从Redis集合中移除stringRedisTemplate.opsForSet().remove(key, followUserId.toString());}}return Result.ok();}// 具体获取好友共同关注代码@Overridepublic Result followCommons(Long id) {// 1.获取当前用户Long userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 2.求交集String key2 = "follows:" + id;Set intersect = stringRedisTemplate.opsForSet().intersect(key, key2);if (intersect == null || intersect.isEmpty()) {// 无交集return Result.ok(Collections.emptyList());}// 3.解析id集合List ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());// 4.查询用户List users = userService.listByIds(ids).stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());return Result.ok(users);}进行测试⛵小结以上就是【Bug 终结者】对 微服务Spring Boot 整合 Redis 实现 好友关注 的简单介绍,Redis 实现好友关注功能也是 利用Set集合、ZSet集合实现这样一个需求,同时,采用Redis来实现更加的快速,减少系统的消耗,更加快速的实现数据展示! 下篇博文我们继续 关注 如何 使用Redis 实现推送消息到粉丝收件箱以及滚动分页查询!————————————————版权声明:本文为CSDN博主「Bug 终结者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_45526437/article/details/128276229
  • [技术讨论] 一分钟自动化部署笔记分享
    部署的发展历程手工管理时代IP地址存放在Excel表里用SSH连接服务器。手工执行,进行部署配置等工作。自动化时代数据库方式管理IP地址—CMDB基于ssh或者agent的分布式脚本执行平台。运用自动化工具,用脚本自动化执行。DevOps阶段统一支持开发和运营的交付工作及环境管理工作。问题一:传统手工部署带来的挑战代码上传及部署方式:手工scp上传代码,开发发送压缩包,手工rz上传,解压部署代码。缺点∶全程人员参与,浪费大量时间。如果节点多,时间就成倍增长。人为干预,可能导致人为失误多。无自动化回滚,或者难以回退问题二:大规模集群部署带来的挑战物理硬件上架系统安装系统环境设置开发工具对策一:自动化基础设施即代码开源自动化工具实现一定功能的子系统,解耦,拼接对策二:DevCloud平台八个功能:项目管理 代码托管 代码检查 编译构建 测试 部署 发布 流水线优点:即开即用,简单高效、大规模云端并发、上下文协作、和华为云紧密集成、一键式部署快速迭代,快速交付、线上线下协同开发、端到端工具链华为云适用于开发 测试 类生产 生产自动化部署:部署过程的每一个步骤都自动化,可以带来包括效能在内的显著的好处。保证了部署的质量,实现了标准化,就降低了系统维护的工作量。自动化部署的目标一键式部署:尽可能的自动化所有部署过程,包括基础设施的创建和部署。多环境支撑:能够适应于开发、测试和生产环境。无服务中断:能够无缝的进行服务升级、切换。支持回滚:可以很容易的回滚到前面的版本以处理意外问题。支持私有云和公有云:不仅要支持自身部署,还要作为服务部署在私有云和公有云上提供部署能力。支持跨网和跨区域部署:要支持跨VPC和多区域部署。发布是针对业务的,部署是针对环境的。部署可以频繁、安全、可持续的进行。部署的版本来自于构建库。使用相同的脚步、相同的部署方式对所有环境进行部署,确保一致性。为了确保安全性和可用性、可以采用蓝绿部署、灰度发布等能力。蓝绿部署一种以可预测的方式发布应用的技术,目的是减少发布过程中服务停止的时间。蓝绿部署原理上很简单,就是通过冗余来解决问题。需要准备两个相同的环境(基础架构)平时在蓝、绿环境通过负载均衡运行业务。升级前把负载切到绿环境。升级时在蓝环境中部署新版本,并进行测试。测试完成,把负载切回蓝环境,然后升级绿环境。绿环境升级测试完成后,系统恢复蓝绿环境共同承担负载。问题考虑数据库与应用部署同步迁移/回滚的问题。需要妥当处理未完成的业务和新的业务。灰度发布/金丝雀部署灰度发布是在原有版本可用的情况下,同时部署一个新版本/金丝雀,测试新版本的性能和表现,以保障整体系统稳定的情况下,尽早发现、调整问题。步骤准备好工件,包括:构建工件,测试脚本,配置文件和部署清单文件。从负载均衡列表中移除掉“金丝雀”服务器。升级“金丝雀”应用(排掉原有流量并进行部署)。对应用进行自动化测试。将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。如果“金丝雀”在线使用测试成功,升级剩余的其他服务器(否则就回滚)。部署服务概述部署服务(CloudDeploy)提供可视化、一键式部署服务,支持并行部署和流水线无缝集成,实现部署环境标准化和部署过程自动化。部署服务具有以下特性:部署任务由原子步骤自由组装编排,免去写脚本实现部署过程,降低门槛。提供20+原子步骤,支持多种主流部署场景提供系统模板Tomcat应用模板、Springboot应用模板、CCE模板等快速创建部署任务。部署过程,每个原子步骤独立输出清晰日志,部署失败能够快速解决失败的原因拓展性强,支持用户自定义开发插件方式接入部署任务。部署任务支持自定义参数,可以在执行部署任务时进行动态修改值。支持无缝集成流水线。部署服务功能模块华为云软件开发服务提供一键式自动化部署,部署机器无需安装代理,过程可视化,主持主流编程语言和技术框架,支持并行部署和流水线无缝集成,实现部署环境标准化和部署过程自动化。DevCloud中部署服务的优势一键式部署主流应用支持Java、PHP、NodeJS、Python、Go和Tomcat应用支持并行部署和流水线无缝集成目标机器无需安装Agent部署操作可以多次高效执行部署服务应用场景简单Web应用和微服务部署应用:用户需要开发简单Web应用或者微服务,并使用软件开发云编译构建和部署。适用场景:适用于Web应用程序和微服务的部署,支持Tomcat、Java、Python、NodeJs、Go、PHP、Ruby语言。大型应用软件和网站部署应用:大型应用软件网站有很多的组件或微服务组合协调,需要软件开发云进行部署。。适用场景︰支持Linux下多服务、多组件、多层次的大型应用,用户需要自定义部署模板,定制适合自己应用的部署脚本和部署参数,并应用流水线编排各个组件的统一部署,实现全系统的自动化部署。部署使用流程添加授信机器:主机名称、主机IP、用户名、口令创建部署任务:任务名称、描述信息选择部署步骤:部署步骤名称、部署需要的配置信息Tomcat:先停止、安装JDK、安装tomcat、选择部署文件来源、启动弹性云服务器ECS弹性云服务器是由CPU、内存、镜像、云硬盘组成的一种可随时获取、弹性可扩展的计算服务器,同时它结合VPC、虚拟防火墙、数据多副本保存等能力,帮助用户打造一个高效、可靠、安全的计算环境,确保服务持久稳定运行。主机部署管理主机是部署目标机器,要将应用部署到该机器,需要先取得该机器的授信,主机要加到某个项目中,并且需要加到主机组里。弹性IP主机名用户名密码云容器引擎CCE云容器引擎(Cloud Container Engine)提供高可靠高性能的企业级容器应用管理服务,支持Kubernetes社区原生应用和工具,简化云上自动化容器运行环境搭建。·用户可以通过CCE实现应用的一站式部署和运维、可定制的DevOps持续交付、灵活的弹性伸缩等功能。容器部署架构cid:link_0cid:link_1,cid:link_21.以下哪项不是传统部署的缺点全程人员参与,浪费大量时间如果节点多,上线速度慢回滚不及时,或者难以回退脚本写错导致业务出错2.以下对于蓝绿部署的描述错误的选项是蓝绿部署的目的是减少发布过程中服务停止时间蓝绿部署要准备两套相同的环境蓝绿部署是新老版本同时在线提供服务蓝绿部署中需要考虑数据库与应用部署同步迁移/回滚问题1.以下哪些是开源部署工具的选型因素大规模的并发能力是否需要编写playbook第三方工具的丰富程度二次开发扩展的能力2.以下哪些是自动化部署的目标脚本管理一键式部署支持回滚支持跨网和跨区域部署3.以下哪些不属于DevCloud平台的功能项目管理容器集群管理部署中间件管理自动化部署工具随着服务器集群规模越来越大,自动化配置和部署这些服务器能够使管理变得非常容易并大大减小管理部署成本,因而得到IT公司的高度重视。目前,市场上主流的四大开源自动化配置管理工具有: Puppet、Chef、Ansible、SaltStack。开源部署工具对比主要选型因素是否需要每台机器部署agent(客户端)学习的门槛大规模并发的能力第三方工具的丰富程度二次开发扩展的能力现有用户使用的规模开源社区的对接Ansible -轻量级的自动化部署工具Ansible是新出现的运维工具,它是基于Python研发的,糅合了众多老牌运维工具的优点,实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。Ansible是基于模块工作的Ansible本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。简单类自然语言的自动化脚本、不需要编程技巧、按顺序执行任务、快速获得生产力强大应用部署、配置管理、工作流编排、应用生命周期编排无需代理架构上无需代理、使用OpenSSH和WinRM、无需开发代理和升级代理、更加安全有效Ansible的架构Ansible:核心模块Connection plugins : Ansible基于连接插件连接到各个主机上,ansible默认使用ssh连接到各个主机,但是也支持其它连接方式Host inventory:定义可管控的主机列表Playbooks:按照所设定编排的顺序执行完成安排任务Core Modules:自带模块Custom Modules:自定义模块Plugins:完成模块功能的补充Playbook的介绍Playbook采用一种可读性很高的且容易被人类阅读的语法的YAML语法编写。该语言在被开发时,YAML的意思其实是:“Yet Another Markup Language”(仍是一种置标语言),格式如下:优势:可读性好、易于实现、和脚本语言的交互性好、每个步骤都配有名称,方便查看结果、脚本模块化、配置灵活Playbook的编写创建目录编写“deploy. json”文件编写“install.yml”文件编写“roles/tomcat/tasks/main. yml”文件编写“group_vars/all”文件打包上传PlaybookPlaybook的执行Playbook - install.yml文件定义角色,playbook入口指定主机全playbook以root执行执行setup,获取远程主机信息Play集Ansible在DevCloud自动化部署架构中的地位执行引擎
  • [技术干货] 【微服务】springboot 整合 dubbo3.0-转载
     前言 随着云原生的兴起,越来越多的微服务化改造在演进过程中也开始提上日程,微服务治理框架能否很好的兼容和支持云原生的体系,也成为很多架构设计者考虑的重要因素;  在微服务治理框架中,dubbo作为一款优秀的服务治理框架,随着dubbo3.0的发布,通过增加的新特性,为云原生的支持带来了福音,也为dubbo2.X过渡到3.0提供了更多好用,且性能高效的亮点;  dubbo3.0新特性介绍 官网新特性介绍 ,下面结合官网的介绍做一些关于 dubbo3.x的新特性总结。  一、注册模型的改变 我们知道,dubbo2.X版本,服务都是以接口的形式注册到注册中心(如zk)。一个接口在注册中心中就是一个数据节点,多个接口就注册多个节点。  当dubbo提供的服务非常多的时候,会给注册中心带来非常大的读写压力,比如在并发量较高的时候,消费端因服务寻址耗费的时间会拉长。而在dubbo3.0版本中对这个问题进行了优化。 dubbo3.0引入服务级别的注册 在dubbo3.0中,只需将应用名和对应的ip、端口注册到注册中心即可。无需再对每个接口进行注册(可通过配置参数进行选择)。以此来减少注册中心的压力。 但是只注册应用,如何查找消费端具体调用的是哪个服务呢? 于是dubbo3.0引入了元数据服务的概念。 具体做法就是,接口提供的服务映射关系,都存在了元数据服务里。元数据服务的数据可以默认存在dubbo内部实现的一个服务里,也可以手动指定存入ZK等服务中。 这样,消费端通过注册中心获取服务列表,然后通过元数据服务映射具体某个接口,进行远程调用。 由此可见,尽管在3.0中以应用纬度进行了注册,看似减轻了注册中心的压力,但引入了元数据服务,也提高了使用的复杂度。二、引入Triple协议 Dubbo3.0新引入了Triple协议。Triple协议可以视为gRPC协议的copy版本。 什么是gRPC? 如果你在了解dubbo3.0之前,或者说没听过gRPC,说明你所涉及的业务或者数据量不需要用到gRPC来达到很高的性能的。所以Triple协议所带来的性能的提升对你而言也是可有可无的。 dubbo认为,http1.X版本性能比较低,主要是因为协议的数据格式复杂,解析带来的一定的性能瓶颈,所以http2.0对性能进行了提升。 而Triple协议是基于http2.0的高性能的基础上,又支持gRPC的远程调用,更具兼容性。这就是Triple协议的特性。 其实在dubbo2.X版本时,dubbo协议是默认的协议,而在3.0版本,Triple协议成为了默认协议。 相比dubbo协议,Triple协议的特点有: triple协议兼容了gPRC(Triple服务可以直接调用gRPC服务,反过来也可以); dubbo协议不是基于的HTTP,不够通用,triple协议底层基于HTTP所以更通用(比如跨语言、跨异构系统实现起来比较方便); dubbo协议不支持流式调用; 三、跨语言调用 跨语言调用对于dubbo来说可以说是一个很大的突破,3.0 支持go语言,python语言等应用进行接口的调用。 涉及到跨语言调用的服务接口,可考虑使用dubbo作为服务。可以使用protobuf格式的数据作为数据传输格式,来进行跨语言调用。 四、SpringCloud的互通 至目前而已,经管两者之间可以实现互通,但是Dubbo3.0与SpringCloud的互通方式也是很繁琐,但看趋势以后的发展肯定会很方便的和SpringCloud进行互通。让我们拭目以待。 dubbo3.0与springboot的整合 接下来演示下与springboot的整合,方便后续在业务中快速运用,完整结构如下: 统一定义服务接口和实体类,被其他工程模块引用; consumer,服务消费方模块; provider,服务提供方模块;   common-service 模块 pomy依赖                      org.projectlombok             lombok             1.18.8          服务接口 import com.congge.entity.User; public interface UserService {     User getByUserId(String userId); } 实体类 @Data @NoArgsConstructor @AllArgsConstructor public class User implements Serializable {       private static final long serialVersionUID = 8728327146677888239L;       private String userId;     private String userName;     private String address; } provider模块     1、pom依赖                             com.congge             common-service             1.0-SNAPSHOT                                 org.springframework.boot             spring-boot-starter             2.6.6                                 org.projectlombok             lombok             1.18.22                                 org.apache.dubbo             dubbo-spring-boot-starter             3.0.7                                 org.apache.dubbo             dubbo-rpc-dubbo             3.0.7                                 org.apache.dubbo             dubbo-rpc-rest             3.0.6                                 org.apache.dubbo             dubbo-registry-zookeeper             3.0.7                  2、核心配置文件 ## 这里的配置属性只是基础配置,如需更多功能配置,请自行扩展 dubbo:   application:     name: dubbo-provider   registry:     address: zookeeper://127.0.0.1:2181   protocol:     name: dubbo     port: 20880 3、服务实现类 @DubboService public class UserServiceImpl implements UserService {       // 模拟数据     private static final List USERS = Arrays.asList(             new User("001", "张三", "北京市东城区"),             new User("002", "李四", "杭州市西湖区"),             new User("003", "王五", "武汉市汉口区")     );       @Override     public User getByUserId(String userId) {         User user = USERS.stream().filter(item -> item.getUserId().equals(userId)).findFirst().get();         return user;     }   }  4、启动类 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;   @SpringBootApplication @EnableDubbo public class ProviderApp {       public static void main(String[] args) {         SpringApplication.run(ProviderApp.class, args);     }   } consumer模块     1、pom依赖                             com.congge             common-service             1.0-SNAPSHOT                                 org.springframework.boot             spring-boot-starter-web             2.6.6                                 org.projectlombok             lombok             1.18.22                                 org.apache.dubbo             dubbo-spring-boot-starter             3.0.7                                 org.apache.dubbo             dubbo-rpc-dubbo             3.0.7                                 org.apache.dubbo             dubbo-rpc-rest             3.0.9                                 org.apache.dubbo             dubbo-registry-zookeeper             3.0.7                  2、核心配置文件 dubbo:   application:     name: dubbo-consumer   registry:     address: zookeeper://127.0.0.1:2181   protocol:     name: dubbo     port: 20880   # 由于zookeeper启动时要占用8080端口,我们要显示指定端口,要不然会端口冲突 server:   port: 8081 3、接口层 为了模拟外部调用效果,这里提供一个接口类  import com.congge.entity.User; import com.congge.service.MyUserService; import com.congge.service.UserService; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;   @RestController public class UserController {       /*@DubboReference     private UserService userService;*/       @Autowired     private MyUserService myUserService;       //http://localhost:8081/user/dubbo?userId=001     @GetMapping("/user/dubbo")     public Object getByUserIdV1(@RequestParam("userId") String userId) {         return myUserService.getUserFromDubbo();     }       //http://localhost:8081/user/rest?userId=001     @GetMapping("/user/rest")     public Object getByUserIdV2(@RequestParam("userId") String userId) {         return myUserService.getUserFromRest();     }   }  4、业务实现层 import com.congge.entity.User; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate;   @Service public class MyUserService {       @Autowired     private RestTemplate restTemplate;       @DubboReference     UserService userService;       public User getUserFromDubbo(){         User user = userService.getByUserId("001");         return user;     }       public Object getUserFromRest() {         User user = restTemplate.getForObject("http://localhost:8082/user/001",User.class);         return user;     } }  5、启动类 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;   @SpringBootApplication public class ConsumerApp {       public static void main(String[] args) {         SpringApplication.run(ConsumerApp.class, args);     }   } 功能测试 1、启动zookeeper服务     2、分别启动生产端和消费端的服务  3、浏览器调用接口模拟   通过上面的案例,我们完成了dubbo3.0与springboot的整合使用,希望对看到的你有用哦。 ———————————————— 版权声明:本文为CSDN博主「逆风飞翔的小叔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/congge_study/article/details/126919969 
  • [云实验室] 基于ServiceStage的微服务开发与部署_步骤
    无实验环境重置按钮
  • [技术干货] 【GDE】【OP环境】微服务后台日志查看指导
    前言:有一些小伙伴在客户现场布置了一套ADC的OP环境。在前端页面显示的报错也许会不全,这个时候就需要登录到后台去看日志,才能分析出是什么问题。以下为一些术语,帮助了解:OC:On Cloud,从字面上理解是要把应用构建和运行在云上。OP:On Premises,指部署在客户服务器上的环境,一般是在客户内部的局域网FS:FusionStage,华为的GDE微服务容器管理平台。也是俗称的“管理面”准备工作需要知道以下信息,才能进行后续操作:FS的登录地址FS登录账号密码登录虚拟机的密码虚拟机root权限的密码需要知道自己要看那个微服务的日志,如我有RPA管理中心的报错,那我就要去看adc-rpa的日志(可以看“模块与服务对照表”)以上信息如果不知道,要找给你装环境的人提供模块与服务对照表领域服务名模块错误码前缀描述编排adc-model编排引擎ADC.RT.MODELADC模型adc-trigger网络业务编排ADC.RT.TRIGGER表数据变更触发器(ADC2ModelBatch中的模型数据同步依赖此微服务)adc-model-batch编排引擎ADC.RT.MODBAT模型数据集中处理(模型数据归档、模型数据同步)adc-service资产服务组ADC.RT.SERVICE运行态逻辑流 (模型服务业务处理:模型服务、模型规则、脚本,翻译器)adc-app-mgt资产服务组ADC.RT.APPMGTapp运行态管理adc-app-mgt-web资产服务组 app管理运行态前端adc-batch资产服务组ADC.RT.BATCHExcel导入导出/文件服务adc-ui用户体验ADC.RT.UI运行态UI(页面、卡片)adc-ui-web用户体验-运行态前台adc-static(微服务名重复)用户体验ADC.RT.STC静态资源adc-intg编排引擎ADC.RT.INTG运行态集成服务adc-mobile终端服务ADC.RT.UI终端SPL引擎运行态微服务adc-mobile-web终端服务-终端SPL引擎运行态静态资源RPAadc-rpaRPAADC_RT_RPARPA运行态管理中心adc-rpa-webRPA-RPA运行态页面日志查看方法下面用查看adc-intg的日志作为例子。1、 找到intg的虚拟机节点1.1、 登录FS管理面管理面信息:访问链接:https://xx.xx.xx.xx:xxxx(如果不知道,要找装环境的人要访问地址)账号:xxxxxx密码:xxxxxx登录页面如下1.2、查看K8S应用部署1.3、搜索找到intg得知adc-intg在这两个节点:(每个环境都不一样,按照实际情况获取)10.151.37.1610.151.37.142.登录虚拟机节点2.1、下载MobaXterm需要下载一个MobaXterm去访问linux虚拟机(也可以去使用其他的工具,方法自定)MobaXterm官网下载地址:https://mobaxterm.mobatek.net/download.html2.2、安装完后,双击点开,新增Session配置完后,双击进入Linux虚拟机,输入密码:xxxxxx。输入密码时,屏幕不会显示密码,继续输入,完成enter即可当显示“Authorized users only, All activities may be monitored and reported”,则说明登录成功2.3、切换root用户控制台输入su root填入密码 xxxxx2.4、 找到intg的PID控制台输入:docker ps | grep intg以上图为例,52396c1bbe02 为pid2.5、进入docker容器控制台输入:docker exec -it 52396c1bbe02 bash2.6、查看日志tailf -n 200 /opt/mateinfo/logs/app/adc-intg.log某些linux镜像没有tailf 可以尝试tailtail -f -n 200 /opt/mateinfo/logs/app/adc-intg.log或者使用less, vi 命令都可以上图为日志,可以拿着这个日志去找华为工程师注意:intg在两个虚拟机节点上,因为系统是负载均衡,所以需要同时登录到两个节点查看。只登录一个节点,如果日志报在另外一个节点,就会miss掉。想要查看其他的微服务也是同样的操作。
  • [页面编排] 微服务调用adc平台服务耗时超时
    如图,微服务调用adc平台服务耗时超时,服务也执行了,这种是正常的吗?
  • [热门活动] 【华为云618】多款中间件、微服务系列产品,助力应用架构与设计现代化
    随着各行各业的竞争加剧,落后的应用架构成为许多企业敏捷创新的阻碍。怎样让你的业务迭代更快?怎样让你的应用跑的更快?转型云原生2.0正当时!#华为云618# 多款中间件、微服务系列产品,助力应用架构与设计现代化!  分布式缓存Redis版,单分片10万QPS,首购低至9.9元 分布式消息服务DMS,最高支持百万TPS,提供Kafka、RabbitMQ、RocketMQ多个版本,首购体验30元起 更有微服务引擎、API网关,等13+产品全场3折起!马上下单,即可参与抽取FreeBuds耳机,满额再送MateBook笔记本!>点击这里,马上进入活动专场<
  • [问题求助] CSE可以管理本地启动的微服务吗?
    CSE可以管理本地启动的微服务吗?本地的服务是不是只需要配置华为云CSE上的注册服务发现地址和配置中心地址就可以管理微服务了?还是说必须要把服务部署后才能用CSE管理呢?
  • [认证交流] 华为云云原生入门级开发者认证学习笔记——第七章
    第7章:华为云微服务架构介绍• 应用架构的演进• 什么是微服务微服务架构是一种架构模式,将单体应用划分成一组小的服务,通过服务之间互相协作,共同实现系统功能。• 微服务的特征• 单体架构:一种软件设计规范,用一种将业务逻辑、数据、显示分离的方法组织代码• 单体架构的优缺点优点:1. 开发和测试简单2. 部署简单3. 运维简单缺点:1. 交付周期长2. 维护成本增加3. 可扩展性差4. 技术选型成本高5. 新成员培养周期长• 从单体架构演进到SOA服务化架构• 微服务架构• 微服务的优势和挑战优势:服务模块边界更清晰、支持独立的部署、允许技术多样性挑战:分布式编程难度大有风险、需处理分布式系统的一致性、增加运维复杂性• 常见的微服务框架1. Spring Cloud2. ServiceComb3. Apache Dubbo• 微服务架构模式1. 微服务之间的RPC通信2. 分布式微服务实例和服务发现3. 配置外置、动态、集中的配置管理4. 提供熔断、限流、隔离、负载均衡等微服务治理能力5. 分布式事务管理能力6. 调用链、集中日志采集和检索• Spring Cloud框架1. 服务注册:服务实例将自身的服务信息注册到注册中心。2. 服务发现:服务实例请求注册中心获取所依赖服务信息。3. 负载均衡:是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。4. API网关:微服务网关,介于客户端与服务器之间的中间层,所有的外部请求都会先经过微服务网关。5. 配置中心:把项目中各种配置、各种参数、各种开关,全都放到一个集中的地方进行统一管理,并提供一套标准的接口。• 熔断:在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体可用性,可暂时切断对下游服务的调用。• 链路追踪:对一次请求涉及多个服务链路进行日志记录,性能监控即链路追踪。• Spring Cloud的技术实现• Spring Cloud实现—服务注册发现和集中配置• Spring Cloud微服务典型部署• 微服务引擎CSE用于微服务应用的云中间件,为用户提供注册发现、服务治理、配置管理等高性能和高韧性的企业级服务能力。可无缝兼容Spring Cloud、ServiceComb等开源生态。• CSE功能介绍1. 无需构建和维护Eureka,Consul等开源软件2. Spring Cloud应用无需修改代码,使用spring-cloud-huawei轻松接入3. 提供用户友好的配置管理,服务治理、安全认证等功能• CSE功能组件与Spring Cloud框架的关系• Spring Cloud Huawei的位置和作用构建存在Spring Cloud应用之上,基于Spring Cloud现有能力构建的,Spring Cloud huawei提供的一系列新的组件。• Spring Cloud Huawei功能介绍• 微服务代码框架• Spring Cloud Huawei接入流程1. 引入依赖包2. 接入服务注册发现中心3. 接入配置中心• Spring Cloud huawei开发引入Spring Cloud Huawei依赖配置微服务信息和CSE引擎信息,从而接入微服务引擎CSE微服务注册发现配置管理服务治理• 华为云应用管理与运维平台功能框架ServiceStage是一个应用托管和微服务管理平台。1. 应用开发:基于spring_cloud_huawei模板进行微服务部署2. 通过流水线功能实现应用的持续交付3. ServiceStage支持应用部署在多种基础设置上云容器引擎CCE部署弹性云服务ECS部署云容器实例CCI部署• ServiceStage支持对应用的全生命周期管理• 应用运维管理服务AOM以云上应用为中心,为企业应用提供一站式立体运维平台• AOM服务可监控的对象AOM日志管理• 如何进行日志采集—LTS日志组:是云日志服务进行日志管理的基本单位,可以创建日志流以及设置日志存储时间。日志流:日志读写的基本单位,日志组中可以创建日志流,方便对日志进一步分类管理。日志采集:采集器支持3种类型:在ECS或私有云节点上安装采集器,通过配置日志路径即可完成采集,用户通过SDK\API接口方式上报日志数据和通过云服务自动完成数据对接。• Service支持对微服务动态治理• 微服务完成部署后,根据微服务的运行情况,配置响应的策略,对服务进行治理。
  • [问题求助] 微服务引擎CSE中配置中心请问下怎么用,翻遍了文档没找到
    先说下我的环境和目的我在s3服务器上搭建了cse环境,下载了下载本地轻量化微服务引擎,搭建了注册中心配置中心,同时下载了demo 的basic中的三个服务注册到注册中心去在30103操作页面配置yaml时就遇到了问题,第一个没理解配置管理怎么用第二个,配置了配置项,但是返回读取的信息还是工程里的yaml配置的信息,并不是从配置中心获取的怎么样才能像spring-cloud-config那样让服务从配置中心读取配置项数据呢?哪位大佬帮忙解决下,谢谢
  • [热门活动] 一起读书吧·DevCloud世界读书日主题活动
    4月23日世界读书日全称“世界图书与版权日”,又称“世界图书日”。其设立目的是推动更多的人去阅读和写作,希望所有人都能尊重和感谢为人类文明做出过巨大贡献的文学、文化、科学、思想大师们,保护知识产权。为支持正版,鼓励开发者培养持续学习的优良品质,华为云软件开发平台DevCloud发起了本次读书日活动,联合清华大学出版社、机械工业出版社精选34本好书样章资源包,为你的软件工程师之路补充粮草~参与流程论坛回帖:#一起读书吧#+推荐图书书名+推荐心得 即可开启隐藏楼层获得大咖书单下载地址![hide]专区地址:https://devcloud.huaweicloud.com/expert/press?utm_source=1[/hide]书籍太多从哪里开始看?不要在收藏夹吃灰啦,专家领读,不迷路!领读视频部分内容展示视频观看地址:https://classroom.devcloud.huaweicloud.com/joinclass/d17483a4aa2f4022b707fc105526b7ac/1你最喜欢哪一本?分享活动给小伙伴,我们会综合下载量和活动结束后社群投票数,有机会对人气最高的图书进行直播解读!华为云软件开发读书群一手资料分享,专家直播领读,尽在此处...