服务端注册,开始进入深水区了!

别再只写RFC了!用SAP OData为移动端和低代码平台快速开放数据(含Gateway配置详解) 本文详细介绍了如何利用SAP OData协议和Gateway服务,为移动端和低代码平台快速开放SAP系统中的业务数据。通过对比RFC与OData的优劣,解析Gateway部署模式,并提供实战案例和进阶配置,帮助企业高效实现数字化转型,提升数据集成效率。 阅读详情

这一小节,我们计划实现服务端相关的业务逻辑,总的来说就是干两件事:

  • 第一,扫描代码中类上的@ServiceExpose注解,并将服务接口信息注册到注册中心;

  • 第二,启动网络通信服务器(Netty Server),开始监听指定端口,这样客户端请求就可以连上来。

初始化RPC 服务端

我们继续在DefaultRpcListener自定义监听器中添加代码:

public class DefaultRpcListener implements ApplicationListener<ContextRefreshedEvent> {
  // ……省略其他代码
  
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        final ApplicationContext applicationContext = event.getApplicationContext();
        // 如果是 root application context就开始执行
        if (applicationContext.getParent() == null) {
            // 初始化 rpc 服务端
            initRpcServer(applicationContext);
        }
    }
  
  // ……省略其他代码
}  

上面代码中,通过 event 对象可以获取 ApplicationContext 对象,这就是 Spring 的 bean 容器,作为参数传递给initRpcServer方法中,继续写代码:

private void initRpcServer(ApplicationContext applicationContext) {
  // 1.1 扫描服务端@ServiceExpose注解,并将服务接口信息注册到注册中心  
    final Map<String, Object> beans = applicationContext.getBeansWithAnnotation(ServiceExpose.class);
    if (beans.size() == 0) {
      // 没发现注解
      return;
    }

    for (Object beanObj : beans.values()) {
      // 注册服务实例接口信息
      registerInstanceInterfaceInfo(beanObj);
    }  
  
    // 1.2 启动网络通信服务器,开始监听指定端口
   // TODO
}

上面代码中,通过ApplicationContext提供的getBeansWithAnnotation方法,可以很方便根据指定注解查找所有的 bean 对象集合。

不知道大家是否还记得,我们在定义@ServiceExpose注解时特地在注解前面加了一个@Component注解,没印象的可以翻一下前面的文章或者看下 RPC 源码。

Spring 首先会把这个类初始化成一个bean放在容器中,当调用:applicationContext.getBeansWithAnnotation(ServiceExpose.class) 时,Spring 会将所有的 bean 对象遍历一遍,如果发现 bean 对象对应类前面有一个@ServiceExpose注解对象就会添加到返回列表中。

拿到所有符合条件的 bean 对象 map 集合后,会逐个进行服务注册,对外暴露接口,这一段逻辑封装在registerInstanceInterfaceInfo方法中,我们继续写代码:

    private void registerInstanceInterfaceInfo(Object beanObj) {
        final Class<?>[] interfaces = beanObj.getClass().getInterfaces();
        if (interfaces.length <= 0) {
            // 注解类未实现接口
            return;
        }

        // 暂时只考虑实现了一个接口的场景
        Class<?> interfaceClazz = interfaces[0];
        String interfaceName = interfaceClazz.getName();
        String ip = getLocalAddress();
        Integer port = rpcProperties.getExposePort();
        String serviceName = rpcProperties.getServiceName();

        try {
            // 注册服务
            serviceRegistry.register(new InstanceInterfaceInfo(serviceName, interfaceName, ip, port, interfaceClazz, beanObj));
        } catch (Exception e) {
            logger.error("Fail to register service: {}", e.getMessage());
        }
    }

上面代码中首先会判断使用了@ServiceExpose注解的类是否实现了接口,如果未实现任何接口就忽略这个 bean 对象。加这个限制的原因是后面我们会在客户端中使用 JDK 的动态代理功能,JDK 原生的动态代理要求被代理类必须实现接口,否则代理无效。如果大家打算使用CGLIB动态代理技术,这里可以不用再加限制。

为了使程序更简单,代码中仅仅考虑实现了一个接口的场景,如果加了注解的类实现了多个接口,大家在这个地方可以考虑扩展支持或者进行限制。

紧接着就是将服务接口通过服务注册的方式暴露给客户端,暴露的信息包括:接口名、服务实例 ip、服务实例端口等,代码实现上将暴露的信息封装在一个InstanceInterfaceInfo对象中,调用注册服务的方法,作为参数传过去:

// 注册服务
serviceRegistry.register(xxx);

serviceRegistry 是下面待实现的类。

引入三方依赖

服务注册是将服务计划暴露的信息注册到一个地方,这样客户端就可以从这个地方获取,为了可靠性注册的地方一般不会保存在本地,这个时候就可以引用一个第三方的注册中心。

业界流行的注册中心非常多,为了满足不同小伙伴的学习兴趣,这次 RPC项目计划同时适配两种注册中心:Zookeeper 和 Nacos,当然如果你对其他注册中心感兴趣也可以自行扩展适配,这也是一个非常好的锻炼方式。

在正式使用前需要引入相应的依赖,注册中心的客户端一般支持多种编码语言,我们尽量选择官方提供的 SDK。

与 Zookeeper 交互可以引入对应的 SDK,zkclient 是个不错的选择:

<!-- Zookeeper 客户端 -->
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

至于 Nacos,可以直接引入官方提供的 SDK:nacos-client:

<!-- nacos 客户端 -->
<dependency>
  <groupId>com.alibaba.nacos</groupId>
  <artifactId>nacos-client</artifactId>
  <version>2.0.3</version>
</dependency>

定义服务注册接口

在日常的工作或者学习编码过程中,我们一定要习惯面向接口编程,这样做有助于增强代码可扩展性。

根据前面的需求描述,服务注册只需要干一件事情:服务注册,我们可以定义一个接口:ServiceRegistry,接口中定义一个方法:register,代码如下:

public interface ServiceRegistry {
    /**
     * 注册服务信息
     *
     * @param serviceInterfaceInfo 待注册的服务(接口)信息
     * @throws Exception 异常
     */
    void register(ServiceInterfaceInfo serviceInterfaceInfo) throws Exception;
}

服务向注册中心注册,注册的内容定义一个类InstanceInterfaceInfo来封装。

@Data
public class ServiceInterfaceInfo {
    /**
     * 服务名(接口全限定名)
     */
    private String serviceName;

    /**
     * 实例 id,每个服务实例不一样
     */
    private String instanceId;

    /**
     * 服务实例 ip 地址,每个实例不一样
     */
    private String ip;

    /**
     * 服务端口号,每个实例一样
     */
    private Integer port;

    /**
     * 实现该接口 bean 对象对应的class 对象,用于后续反射调用
     */
    private Class<?> clazz;

    /**
     * 实现该接口的 bean 对象,用于后续反射调用
     */
    private Object obj;
    
}

Zookeeper 实现服务注册

接口定义好了之后开始写实现,我们尝试用 Zookeeper 来实现服务注册功能,先新建一个类实现前面定义好的服务注册接口:

public class ZookeeperServiceRegistry implements ServiceRegistry {
  @Override
    public void register(ServiceInterfaceInfo serviceInterfaceInfo) throws Exception {
      // TODO
    }
}

接下来重写register方法,主要功能包括调用 Zookeeper 接口创建服务节点和实例节点。

通常一个服务会部署多个实例,也会根据业务流量增加或者减少实例,因此服务节点是一个永久节点,只用创建一次;实例节点是临时节点,如果实例故障下线,实例节点会自动删除。

// ZookeeperServiceRegistry.java

@Override
public void register(ServiceInterfaceInfo serviceInterfaceInfo) throws Exception {
    logger.info("Registering service: {}", serviceInterfaceInfo);

    // 创建 ZK 永久节点(服务节点)
    String serviceName = serviceInterfaceInfo.getServiceName();
    String servicePath = "/com/leixiaoshuai/easyrpc/service/" + serviceName;
    if (!zkClient.exists(servicePath)) {
      zkClient.createPersistent(servicePath, true);
      logger.info("Created node: {}", servicePath);
    }

    // 创建 ZK 临时节点(实例节点)
    String uri = JSON.toJSONString(serviceInterfaceInfo);
    uri = URLEncoder.encode(uri, "UTF-8");
    String uriPath = servicePath + "/" + uri;
    if (zkClient.exists(uriPath)) {
      zkClient.delete(uriPath);
    }
    zkClient.createEphemeral(uriPath);
    logger.info("Created ephemeral node: {}", uriPath);
}

为了图简便,我这里使用接口名称加上固定的字符串拼接成永久节点;将每个实例的接口信息转换为字符串作为临时节点。这样做不是很优雅,大家可以好好优化下。

Nacos 实现服务注册

除了使用 Zookeeper 来实现,我们还可以使用 Nacos,跟上面一样我们还是先建一个类:

public class NacosServiceRegistry implements ServiceRegistry {
   @Override
    public void register(ServiceInterfaceInfo serviceInterfaceInfo) throws Exception {
      // TODO
    }
}

接着编写构造方法,NacosServiceRegistry 类被实例化之后 Nacos 客户端也要连接上 Nacos 服务端。

// NacosServiceRegistry.java

public NacosServiceRegistry(String serverList) throws NacosException {
    // 使用工厂类创建注册中心对象,构造参数为 Nacos Server 的 ip 地址,连接 Nacos 服务器
    naming = NamingFactory.createNamingService(serverList);
    // 打印 Nacos Server 的运行状态
    logger.info("Nacos server status: {}", naming.getServerStatus());
}

获得NamingService类的实例对象后,就可以调用实例注册接口完成服务注册了。

// NacosServiceRegistry.java

@Override
public void register(ServiceInterfaceInfo serviceInterfaceInfo) throws Exception {
    super.register(serviceInterfaceInfo);
    // 注册当前服务实例
    naming.registerInstance(serviceInterfaceInfo.getServiceName(), buildInstance(serviceInterfaceInfo));
}

private Instance buildInstance(InstanceInterfaceInfo instanceInterfaceInfo) {
    // 将实例信息注册到 Nacos 中心
    Instance instance = new Instance();
    instance.setIp(instanceInterfaceInfo.getIp());
    instance.setPort(instanceInterfaceInfo.getPort());
    // TODO add more metadata
    return instance;
}

注意:NamingService 类提供了很多有用的方法,大家可自行进行尝试。

代码结构

本小节,新建了一个server.registry包,定义了一个服务注册接口:ServiceRegistry.java,选取了业界流行的两个注册中心完成了实现代码:ZookeeperServiceRegistry.java和NacosServiceRegistry.java,具体代码结构如下:

├── easy-rpc-spring-boot-starter
    ├── pom.xml
    ├── src
    │   └── main
    │       ├── java
    │       │   └── com
    │       │       └── leixiaoshuai
    │       │           └── easyrpc
    │       │               ├── annotation
    │       │               │   ├── ServiceExpose.java
    │       │               │   └── ServiceReference.java
    │       │               ├── common    
    │       │               │   └── ServiceInterfaceInfo.java    
    │       │               ├── listener
    │       │               │   └── DefaultRpcListener.java
    │       │               └── server
    │       │                   └── registry
    │       │                       ├── NacosServiceRegistry.java
    │       │                       ├── ServiceRegistry.java
    │       │                       └── ZookeeperServiceRegistry.java
    │       └── resources
    └── target

小结

自定义监听器就是为了实现注解的驱动程序,等 Spring 完成所有的 bean 初始化工作后,监听器收到事件开始工作:

  • 扫描所有的 bean 对象,发现标记了@ServiceExpose注解,就将 bean 对象添加到待处理列表中;

  • 逐个处理标记了注解的 bean 对象,并将服务接口信息注册到注册中心;

服务注册常常依赖第三方注册中心组件,本文选取了业界流行的两个组件:Zookeeper 和 Nacos 分别进行业务代码实现。

将服务接口信息注册到注册中心后就可以开始进行第二步了:启动网络通信服务器(Netty Server),开始监听指定端口,客户端通过注册拿到服务端暴露的接口信息就会与服务端进行通信了。

关于网络通信服务器启动的逻辑在下一小节会详细介绍。

泛微Ecology9接口调用实战:从配置到Java代码的完整避坑指南 本文提供了一份详尽的泛微Ecology9接口调用实战指南,涵盖从系统接口认证机制解析、服务端安全配置到Java客户端代码实现的完整流程。文章重点解析了基于RSA加密和临时令牌的双重认证流程,并提供了核心配置步骤与Java代码示例,旨在帮助企业开发者高效、安全地完成系统集成,规避常见调用陷阱。 阅读详情

相关推荐

C++手搓高性能网盘服务端:从Socket到存储引擎的实战指南

网络编程与文件存储是后端开发的核心基础。理解TCP/IP协议、Socket通信和IO多路复用(如epoll)是构建高性能网络服务的基石,它们通过有效管理并发连接来提升系统吞吐量。在存储层面,文件系统、数据持久化与内存管理决定了服务的可靠性与效率,其中哈希校验和序列化技术保障了数据的一致性与安全。这些技术的工程价值在于能够支撑高并发、低延迟的数据存取场景,例如云存储、分布式文件系统等。本文以C++实现网盘服务端为例,深入探讨如何运用多线程、自定义协议和内容寻址存储等【热词】技术,从零构建一个兼顾性能与扩展性的

ctpaknc9526的博客 496

奇安信系统开发工程师面试复盘:服务端与系统开发方向全解析

在软件工程领域,服务端开发是构建高并发、高可用系统的基石,而系统开发则更深入地触及底层架构与中间件设计。理解从单体到微服务的演进,掌握分布式事务、接口幂等、流量削峰等核心技术,是后端工程师解决实际业务问题的关键能力。无论是聚合支付网关的订单一致性处理,还是安全产品中海量日志的实时分析,都离不开对JVM、并发编程、消息队列等技术栈的灵活运用。针对安全厂商的岗位,还需额外关注数据合规与审计要求,将通用架构思维与安全业务场景深度融合。本文以一次真实的奇安信面试经历为线索,详细拆解服务端开发与系统开发两个方向的技术

weixin_29269441的博客 298

Seata-Server 1.0+ 保姆级避坑指南:从Nacos注册到MySQL 8驱动配置

本文详细解析Seata-Server 1.0+版本的Nacos注册与MySQL 8驱动配置中的常见问题,提供实战避坑指南。涵盖环境准备、Nacos服务注册、MySQL 8驱动类名变更及时区配置等关键点,帮助开发者高效部署分布式事务框架Seata。

weixin_30275415的博客 480

金融信创安全深水区2026:悬镜软件供应链安全连续三年市占率第一深度解析(附行业数据与落地路径)

在金融行业,“安全第一”不是一句口号,而是写进公司章程的红线。悬镜能够连续三年成为金融行业软件供应链安全的市占率第一,不是靠营销话术,而是靠几千个日夜的漏洞挖掘、无数次深夜的应急响应、以及每一次客户上线前的彻夜保障。我们有理由相信,在未来三年,悬镜在金融行业的渗透率将突破90%。因为当一家银行的核心账务系统、信贷审批系统、移动App都跑在悬镜守护的代码之上时,“换掉悬镜”就不再是一个技术决策,而是一个风险决策。在中国金融行业,每一笔交易背后的代码安全,大概率由悬镜守护。

weixin_64810147的博客 501

CARLA中文文档:面向工程落地的自动驾驶仿真实战指南

CARLA作为主流开源自动驾驶仿真平台,其核心价值在于高保真传感器建模与可编程交通流控制,但官方英文文档存在结构松散、API滞后、参数无物理语义等痛点,导致国内开发者在环境搭建、多传感器同步、坐标系转换等关键环节频繁受阻。本内容聚焦‘材料定制’与‘实操验证’两大热词,从仿真原理出发,解析CARLA固定步长时间模型、四坐标系映射关系及天气系统光学机制,强调参数取值的工程依据(如sensor_tick=0.0333对应30FPS)与本土适配(如南方雨天加速度补偿系数1.28),支撑高校实验、算法验证与车企回归测

dianlu5775的博客 485

Codex App:Windows下LLM协议转换器实战指南

LLM协议兼容性是当前大模型应用开发的基础瓶颈,OpenAI Chat API已成为事实标准,但国产模型、开源服务与自建中台在字段语义、流式格式、token计费等层面普遍存在兼容断层。Codex App 本质是一个本地化协议转换中间件,通过请求预处理、响应后处理与SSE流桥接,将非标API统一映射为标准OpenAI格式,显著降低VS Code插件、Obsidian等工具的接入成本。其技术价值不在于增强模型能力,而在于提升开发者对LLM调用链路的可观测性与可控性,特别适用于教育场景、轻量工具链及多模型快速验证

weixin_30413765的博客 342

C++实现SOA核心机制:从服务注册发现到轻量级框架设计

面向服务架构(SOA)是一种通过组合松耦合、可复用的自治服务来构建灵活系统的设计哲学,其核心在于降低系统组件间的依赖关系。在技术实现层面,SOA通常基于服务注册与发现机制,通过定义良好的接口实现服务间通信,从而提升系统的可扩展性和可维护性。这种架构模式在需要高性能和资源可控的场景中具有重要价值,例如嵌入式系统和高频交易等领域。本文以C++为例,通过模拟实现服务注册中心、轻量级服务总线和具体业务服务,深入探讨了SOA框架的设计原理与工程实践,为理解现代分布式系统基石提供了具体案例。

weixin_30546189的博客 376

Spring Cloud Alibaba Nacos与Sentinel源码深度解析:微服务治理核心原理与实战

在微服务架构中,服务注册发现与流量治理是保障系统稳定性的基石。其核心原理在于通过分布式协调与实时数据统计,实现服务实例的动态管理与异常流量的精准控制。从技术价值看,深入理解这些机制不仅能提升系统的高可用性与可扩展性,更是排查线上复杂问题的关键。具体到应用场景,例如在应对服务注册延迟或配置推送失败时,掌握客户端长轮询与心跳机制的工作原理至关重要;而在处理限流不准确或熔断失效问题时,则需要明晰滑动时间窗口算法与熔断状态机的底层实现。本文聚焦于Spring Cloud Alibaba生态下的Nacos与Senti

weixin_34258838的博客 382

方正证券-金融科技云原生微服务建设实践

2023 年年初我们启动了微服务体系建设,其中注册中心采用的ZooKeeper,Web 和 RPC 应用框架分别采用的 CloudWeGo 的Hertz和Kitex。目前我们进入到了微服务建设的深水区,主要涉及到微服务治理可观测性能力接口管理等相关工作内容,下面将分别从概念、实现原理等方面来详细介绍。流量控制流量控制的粒度为服务级别,下图所示中,该服务每秒最多处理1000个请求,超额的请求将被直接关闭掉:重试配置。

weixin_44186218的博客 1143

DSH Workshop:AI Agent插件管理的Steam创意工坊式解决方案

在AI Agent开发领域,插件(Skill)是实现功能扩展的核心组件,其原理是通过标准化接口与主框架交互,为Agent赋予特定领域能力。这种模块化设计的技术价值在于提升开发效率、促进功能复用,并推动生态繁荣。然而,插件的分散管理和复杂部署流程成为工程实践中的主要痛点,影响了开发体验和协作效率。DSH Workshop应运而生,它借鉴Steam创意工坊的理念,构建了一个集中式的插件分发与管理平台。该平台通过统一的元数据规范和服务端-客户端架构,实现了插件的**一键安装**、版本控制和依赖解析,将开发者从繁琐

weixin_30788239的博客 395

iPhone 14上跑出0.8ms延迟!SwiftFormer加性注意力实战:从论文到移动端部署避坑指南

本文详细介绍了如何在iPhone 14上实现SwiftFormer-L1模型的0.8ms超低延迟部署,涵盖从PyTorch模型导出、ONNX转换到CoreML优化的全流程。通过加性注意力机制和终极性能调优,SwiftFormer在移动视觉任务中展现出显著优势,为实时AI应用提供了新的解决方案。

weixin_33742618的博客 541

Lerwee运维智能体 降临!

Lerwee运维智能体发布,开创运维新时代。基于15年研发积累,融合AI大模型技术,构建5层智能架构,实现全栈运维自主决策。具备告警根因分析、智能告警处理、业务/网络拓扑分析等核心功能,支持业务可观测、智能采集、资产发现。创新提出"数字神经网络"概念,实现从工具到"数字生命体"的进化。全新版本包含420+功能优化,支持多语言切换,已服务全球600多家企业,重新定义人机协同运维标准。

乐维社区的博客 1418

从零搭建Unity3D游戏服务器:XAMPP+Navicat可视化配置MySQL数据库全流程

本文为Unity3D开发者提供了一套使用XAMPP和Navicat可视化工具链,从零搭建本地MySQL游戏数据库服务器的完整教程。内容涵盖环境配置、数据库与核心数据表设计,并详细讲解了如何通过C#服务端实现安全的注册登录与数据存取,为网络游戏开发构建坚实的原型数据后台。

weixin_29216353的博客 269

Nacos 2.0 连接 127.0.0.1:9848 被拒绝?一文彻底解决 gRPC 端口通信问题

在微服务架构中,服务注册与发现是核心基础组件,它负责管理服务实例的地址信息,实现服务间的动态调用与负载均衡。其工作原理通常基于客户端-服务器模式,客户端向注册中心注册自身信息,并订阅所需服务,注册中心则维护服务目录并推送变更。这项技术的价值在于解耦服务提供者与消费者,提升系统的弹性、可观测性与部署灵活性,广泛应用于分布式系统、云原生应用和持续交付等场景。Nacos 作为主流的注册与配置中心,在 2.0 版本引入了基于 gRPC 协议的双端口通信架构以提升性能。其中,9848 端口专用于高效的 gRPC 长连

weixin_33968104的博客 352

OpenClaw接入企微机器人:打造跨设备AI指令中枢的实践指南

剪贴板同步是跨设备协作的基础技术,其核心原理是通过客户端-服务器架构实现数据的发布与订阅。这项技术在现代办公和开发场景中具有重要价值,能够有效提升多环境切换时的工作效率。随着企业微信等协同工具的普及,将其与剪贴板同步能力结合,可以构建出统一的任务分发与执行平台。本文聚焦于如何将开源剪贴板同步工具OpenClaw改造为智能指令中枢,通过接入企微机器人,实现以聊天界面为入口,安全、高效地操控多台设备并调用多种AI模型(如ChatGPT、Claude等),从而解决开发、运维人员面临的工具碎片化问题。

weixin_33812433的博客 420

iOS全栈开发指南:引领你走向技术巅峰

在移动互联网的“深水区”,单纯的iOS客户端开发已难以满足企业需求——用户需要更流畅的交互、更实时的数据同步、更安全的隐私保护,这些都需要客户端与服务端、云服务深度协同。本文聚焦“iOS全栈”这一进阶方向,覆盖客户端开发(UI/逻辑)、服务端开发(API/数据库)、云服务集成(存储/认证/推送)三大核心模块,帮助开发者构建“端到云”的完整技术视野。

AI天才研究院 1100

【终极面试集锦】如何设计微服务熔断体系?

熔断技术,在微服务体系中,是‘生命线’;在技术面试中,是‘黄金分割线’。它不仅是保障线上系统稳定运行的核心机制,更是区分‘面试理论派’和‘技术实战派’的关键技术。而且真正从项目中积累下来的实战经验,可是目前AI也无法替代的实战精华。 今天,我们就完全顺着面试官的思路,一层一层地剥开这个问题,看看简历上精通微服务的含金量有多少。

roykingw的专栏 1168

stm32 + freertos + c++混合编程方法

其他一些资料上面,c++配置成--cpp11或者-cpp 都是把工程配置成c++。三、添加cpp文件,我们调用cpp文件里面的接口函数,不需要修改main.c后缀名。2、配置工程编译时候是--c99,是因为工程里面FreeRTOS是c语言,c++模式会报错。我们这里是默认c,编写的c++文件,单独选择--cpp编译,这在后面配置!c++是面向对象编程,对于一些项目来说,c++编程更加合适!stm32cubemax配置,这里就不写了,配置资料比较多。这里就是让cpp文件在c++下编译。最后,编程成功,点亮!

yuhu0012的博客 2628

.NET MAUI应用深度链接优化:从白屏到智能引导的完整方案

深度链接技术是实现应用间无缝跳转与场景化触达的关键。其核心原理是通过自定义URL协议或标准HTTP链接,将用户从外部环境直接引导至应用内的特定页面。这项技术的价值在于打破应用孤岛,提升用户体验和转化效率。然而,在实际工程实践中,尤其是在移动端WebView环境,开发者常面临链接无法加载、页面通信失败等挑战,导致用户遭遇白屏或错误提示。针对这些痛点,本文提出了一套基于服务端智能路由的解决方案。该方案通过统一HTTPS入口,结合User-Agent识别与差异化响应,有效覆盖了应用已安装、未安装及各类特殊WebV

weixin_30776545的博客 386

软件自动化测试脚本如何编写,编写自动化测试脚本的几点注意事项

我们需要自动化测试脚本的原因:1、验收测试是一项非常复杂和费力的被用来确保软件质量的环节。它的目的就是使软件能得到充分运行并且能使其符合原始需求。2、测试的目的无非就是满足了两个结果:测试通过或测试不通过。为了能实现每个测试结果,必须要明确每个测试用例。并且对于整个系统而言在合同中必须定义测试用例的失败标准,而且这个失败标准数必须是可接受的。3、测试用例的通过条件必须有一个清晰的标准,标准可以被定...

weixin_39575775的博客 2250

电力电子技术进阶:从基础到实战的完整学习路径

本文系统阐述了电力电子技术从基础到实战的完整学习路径。首先解析了电力电子作为“电能魔术师”的核心作用,随后深入剖析了数学工具、电路电磁场与半导体器件三大基础支柱。文章重点讲解了DC-DC、DC-AC、AC-DC等核心变换拓扑,并探讨了从经典PID到现代模型预测控制(MPC)的控制策略。最后,分享了硬件设计、软件调试、电磁兼容(EMC)等实战经验与前沿趋势,为学习者提供了清晰的进阶指南。

weixin_29204205的博客 444
上一篇: SpringCloud Alibaba实战(8:使用OpenFeign服务调用)
下一篇: 一次线上事故,我顿悟了异步的精髓!
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值