Spring Boot整合Zookeeper实现配置中心

spring boot3 使用zookeeper做注册中心、配置中心 RefreshScope是用来动态更新demo的值的,比如我在项目启动后,如果要修改demo的值,在不重启的情况下更新项目的demo值,加上注解之后就会自动更新。对于 Zookeeper Config 来说,它会读取 Zookeeper /{root}/{spring.application.name}/ 和 /{root}/{default-context}/ 目录下的节点。我们要用zookeeper配置中心的话 ,要知道具体系统怎么读zookeeper的上面的路径。 阅读详情
AI摘要

本文详细介绍了如何使用Zookeeper作为配置中心,通过SpringBoot整合Zookeeper实现动态配置更新。文章覆盖了Zookeeper配置中心的基本原理,SpringBoot项目中依赖的引入,配置文件的修改,自定义配置类的编写,以及配置测试接口的实现。同时,针对在实践过程中遇到的异常问题,提供了具体的解决方案。

简介

使用背景

说到配置中心,目前市面上用的较多的配置中心都广为人知,比如百度的Disconf、Spring Cloud Config、携程的Apollo、阿里的Nacos等。由于项目组一直是使用的zookeeper作为配置中心,所以来学习使用。

实现原理

在Zookeeper建立一个根节点,比如/CONFIG,代表某个配置文件。将配置文件中的信息作为根节点的子节点存储,比如配置项timeout=3000,在Zookeeper中展现为:/CONFIG/timeout,节点内容是3000。然后让所有使用到该配置信息的应用机器集成Zookeeper并监控/CONFIG的状态,一旦配置信息也就是子节点发生变化,每台应用机器就会收到ZK的通知,然后从ZK中获取新的配置信息应用到系统中。
实现原理细节可参考:https://cloud.tencent.com/developer/news/365803

Spring Boot整合Zookeeper

引入依赖

		 <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.3.0</version>
        </dependency>

Curator是Apache软件基金会下的一个开源框架,目前是Apache下的顶级项目。Curator是ZooKeeper的一个Java客户端库,包括一个高层API框架和一些实用程序,使得开发人员在使用ZooKeeper时更容易,更可靠。
参考:https://blog.youkuaiyun.com/hzygcs/article/details/88171620

修改配置application.properties

由于只是简单使用,配置连接即可

zookeeper.url=192.168.1.106:2181

定义配置类

ZookeeperConfig.java

@Configuration
public class ZookeeperConfig {

    Properties properties = new Properties();
    //可以理解curatorFramework为客户端,基本操作都由它完成
    CuratorFramework curatorFramework = null;
    TreeCache treeCache = null;

    @Value("${zookeeper.url}")
    private String zkUrl;
    //定义顶级
    private final String CONFIG_NAME = "/zookeeper";

    //初始化
    private void init() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        curatorFramework = CuratorFrameworkFactory.newClient(zkUrl, retryPolicy);
        treeCache = new TreeCache(curatorFramework, CONFIG_NAME);
    }

    /**
     * 设置属性
     * @param key
     * @param value
     * @throws Exception
     */
    public void setProperties(String key, String value) throws Exception {
        String propertiesKey = CONFIG_NAME + "/" + key;
        Stat stat = curatorFramework.checkExists().forPath(propertiesKey);
        if(stat == null) {
            curatorFramework.create().forPath(propertiesKey);
        }
        curatorFramework.setData().forPath(propertiesKey, value.getBytes());
    }

    /**
     * 获取属性
     * @param key
     * @return
     */
    public String getProperties(String key) {
        return properties.getProperty(key);
    }

    @PostConstruct
    public void loadProperties() {
        try {
            init();
            curatorFramework.start();
            treeCache.start();

            // 从zk中获取配置放入本地配置中
            Stat stat = curatorFramework.checkExists().forPath(CONFIG_NAME);
            if(stat == null) {
                curatorFramework.create().forPath(CONFIG_NAME);
            }
            List<String> configList = curatorFramework.getChildren().forPath(CONFIG_NAME);
            for (String configName : configList) {
                byte[] value = curatorFramework.getData().forPath(CONFIG_NAME + "/" + configName);
                properties.setProperty(configName, new String(value));
            }

            // 监听属性值变更
            treeCache.getListenable().addListener(new TreeCacheListener() {
                @Override
                public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                    if (Objects.equals(treeCacheEvent.getType(), TreeCacheEvent.Type.NODE_ADDED) ||
                            Objects.equals(treeCacheEvent.getType(), TreeCacheEvent.Type.NODE_UPDATED)) {
                        String updateKey = treeCacheEvent.getData().getPath().replace(CONFIG_NAME + "/", "");
                        properties.setProperty(updateKey, new String(treeCacheEvent.getData().getData()));
                        System.out.println("数据更新: "+treeCacheEvent.getType()+", key:"+updateKey+",value:"+new String(treeCacheEvent.getData().getData()));
                    }
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

配置测试接口

ZkController.java

@RestController
public class ZkController {

    @Autowired
    private ZookeeperConfig zookeeperConfig;


    @GetMapping("get/{key}")
    public String getProperties(@PathVariable String key) {
        return zookeeperConfig.getProperties(key);
    }

    @GetMapping("set/{key}/{value}")
    public String setProperties(@PathVariable String key, @PathVariable String value) throws Exception {
        zookeeperConfig.setProperties(key, value);
        return "配置成功";
    }
}

验证

zookeeper节点情况如下:
在这里插入图片描述

浏览器中输入:http://localhost:8080/get/hehe 可以获取到,使用工具对其他两个node进行更新,程序控制台也可以查看到更新数据信息:

在这里插入图片描述
在这里插入图片描述

当验证set的时候,程序报错:
在这里插入图片描述

org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for /zookeeper/123
	at org.apache.zookeeper.KeeperException.create(KeeperException.java:106) ~[zookeeper-3.5.7.jar:3.5.7]
	at org.apache.zookeeper.KeeperException.create(KeeperException.java:54) ~[zookeeper-3.5.7.jar:3.5.7]
	at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:1637) ~[zookeeper-3.5.7.jar:3.5.7]
	at org.apache.curator.framework.imps.CreateBuilderImpl$17.call(CreateBuilderImpl.java:1180) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.framework.imps.CreateBuilderImpl$17.call(CreateBuilderImpl.java:1156) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.connection.StandardConnectionHandlingPolicy.callWithRetry(StandardConnectionHandlingPolicy.java:67) ~[curator-client-4.3.0.jar:na]
	at org.apache.curator.RetryLoop.callWithRetry(RetryLoop.java:81) ~[curator-client-4.3.0.jar:na]
	at org.apache.curator.framework.imps.CreateBuilderImpl.pathInForeground(CreateBuilderImpl.java:1153) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.framework.imps.CreateBuilderImpl.protectedPathInForeground(CreateBuilderImpl.java:607) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:597) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:575) ~[curator-framework-4.3.0.jar:4.3.0]
	at org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:51) ~[curator-framework-4.3.0.jar:4.3.0]
	at com.springboot.springbootzookeeper.config.ZookeeperConfig.setProperties(ZookeeperConfig.java:55) ~[classes/:na]
	at com.springboot.springbootzookeeper.controller.ZkController.setProperties(ZkController.java:28) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_101]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_101]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]

2020-06-29 16:57:18.173  INFO 13664 --- [168.1.106:2181)] org.apache.zookeeper.ClientCnxn          : Unable to read additional data from server sessionid 0x10000654e3b001a, likely server has closed socket, closing socket connection and attempting reconnect
2020-06-29 16:57:18.273  INFO 13664 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager     : State change: SUSPENDED

感谢
https://blog.youkuaiyun.com/forget_me_not1991/article/details/80902055
https://www.jianshu.com/p/57ac51e9987f

将curator-recipes版本调整为2.8.0后,可以将节点添加成功。
在这里插入图片描述

2020-06-29 17:07:11.622  INFO 14628 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-06-29 17:07:11.625  INFO 14628 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
数据更新: NODE_ADDED, key:123,value:192.168.137.1
数据更新: NODE_UPDATED, key:123,value:123

在这里插入图片描述

SpringBoot+ZooKeeper+ZKUI+Drools 实现应用配置中心及业务规则动态加载 本文目的: 使用ZooKeeper作为SpringBoot应用的配置中心 应用中使用到的业务规则存储在Zookeeper中,规则更新后在不重启应用的情况下通知应用动态重载规则 1.zookeeper简介Zookeeper是一个高性能,分布式的,开源分布式应用协调服务。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务,比如同步,配置管理,集群管理,命名空间。它被设计为易于编程,使用文件系统 阅读详情

相关推荐

SpringBoot集成Zookeeper

Zookeeper 伪集群安装部署操作 Java操作Zookeeper实现分布式锁和队列 文章目录分布式事物CAP理论CAP定理的应用BASE理论2PC提交3PC提交zookeeper集群的角色ZAB协议的核心思想ZAB协议两种模式ZAB协议消息广播流程图ZAB协议奔溃恢复SpringBoot集成Zookeeper实战 分布式事物 分布式事务是指事务的参与者,支持事务的服务器,资源服务器分别位于...

u010391342的博客 5万+

zookeeper之配置中心

配置中心工作流程 服务启动时,加载远程配置到配置中心 当需要修改配置时,通过配置中心后台控制台修改配置 配置中心的配置改动会同步到每个server上

Lucifer ZHAO 3867

Spring Boot整合Dubbo+Zookeeper实现RPC调用

通过一个示例说明Dubbo+Zookeeper在Spring Boot中的应用。

tangjieqing的博客 597

springboot使用zookeeper作为配置中心

在使用springcloud做微服务时,大家可以使用配置中心对配置做实时管理,刷新,即时生效;但是springCloud的微服务需要依赖很多组件,如果我们只是一个springboot应用可以使用配置中心管理配置吗?其实很多公司提供了这种配置管理的框架, 例如,百度的disconf,ctrip apollo,淘宝 diamond,spring-cloud/spring-cloud-config,这...

龚艺洋的博客 1万+

Spring Boot与Zookeeper整合实现权限控制

在微服务架构中,服务之间的调用和配置管理变得尤为重要。Zookeeper作为一个高可用的分布式协调服务,常用于服务注册、配置管理等场景。Spring Boot,以其开箱即用的特性,简化了许多传统应用的配置和部署流程。将Spring Boot与Zookeeper整合,可以实现服务的自动化管理,为微服务架构提供更加强大和灵活的基础设施。整合Spring Boot与Zookeeper主要有以下几个目的:服务发现。

weixin_35750747的博客 904

保姆级教程:在RK3568 Debian系统上搞定AIC8800 WiFi与蓝牙驱动(含固件路径与开机自启脚本)

本文提供在RK3568 Debian系统上配置AIC8800 WiFi与蓝牙驱动的保姆级教程,涵盖驱动移植、固件部署、开机自启脚本等关键步骤。通过详细的硬件连接指南、内核配置示例和常见问题解决方案,帮助开发者快速实现无线模块的全功能配置,特别适合嵌入式Linux开发者参考。

weixin_28684825的博客 378

java 配置中心_Spring boot外部配置(配置中心化)详解

前言在项目中为了灵活配置,我们常采用配置文件,常见的配置文件就比如xml和properties,springboot允许使用properties和yaml文件作为外部配置。现在编译器对于yaml语言的支持还不够好,目前还是使用properties文件作为外部配置。在Spring cloud config出来之前, 自己实现了基于ZK的配置中心, 杜绝了本地properties配置文件, 原理很简单...

weixin_42382703的博客 497

增量编码器资讯大全

增量编码器是什么 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小,按照工作原理编码器可分为增量式和绝对式两类。 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。 编码器是把角位移或直线位移转换成电信号的一种装置。前者称为码盘,后者称码尺.按照读出方式编码器可以分为接触式和非接触式两种.接触式采...

kindele的博客 6008

Spring Boot 整合 ZooKeeper:服务发现、配置中心与分布式锁实战

本文介绍了在Spring Boot中集成ZooKeeper实现分布式协调服务的方法。主要内容包括: ZooKeeper简介及其节点类型(持久/临时/顺序节点)和典型用途 使用Docker快速搭建ZooKeeper测试环境 Spring Boot项目所需的Maven依赖配置 服务注册实现:通过Spring Cloud Zookeeper Discovery将订单服务注册到ZooKeeper 服务发现与调用:创建消费者服务,使用@LoadBalanced RestTemplate实现负载均衡调用 文章提供了完整

qq_29029209的博客 644

RDMA性能调优实战:如何用ib_*命令榨干你的Mellanox网卡带宽?

本文深入探讨了如何利用ib_*命令工具集对RDMA网络进行深度性能调优,以充分释放Mellanox网卡的带宽潜力。文章从理解Send/Write/Read三种核心通信原语的差异入手,逐步指导读者通过调整消息大小、队列深度、内联数据等关键参数,并结合系统级的NUMA绑定、中断亲和性等优化策略,实现从基准测试到逼近硬件极限的性能提升。

weixin_29306011的博客 87

BDD测试之Behave使用入门

BDD测试(Behavior-Driven Development Testing)是一种基于“行为驱动开发”(BDD)理念。

想要成为酷盖但是失败的小明 580

(十三)SpringBoot整合当当网config toolkit管理配置信息

使用configtoolkit的原因在大型分布式集群应用中,配置不应该分散在每个集群节点。应该统一配置中心,有两个好处:(1)配置全局管理,一处修改,则重启程序时不用每次都修改配置文件。(2)配置文件配置热更新,程序中应用到的配置,可以集中修改,然后每个节点立刻生效。官网地址https://github.com/dangdangdotcom/config-toolkithttps://github...

这个名字想了很久 3240

VisionPro 机器视觉案例 之 彩色保险丝个数统计

CogColorSegmenterTool CogColorMatchTool

机器视觉李小白的博客 2352

源码时代Java干货分享|带你认识Zookeeper 分布式服务框架

本质 它是一个分布式服务框架,是Apache Hadoop 的一个子项目 提供一种集中式信息存储服务,用于解决分布式应用中的一些数据管理问题 简单来说 zookeeper = 文件系统 + 监听通知机制。 特点 数据存在内存中 类似文件系统的树形结构(文件和目录) 高吞吐量和低延迟 集群高可靠 作用 实现分布式统一配置中心 服务注册中心 分布式锁等功能 用于分布式应用...

ITsource 206

硬方案——几种实用的恒流源电路设计方案,敬请收藏(运放、三极管在手,让你玩出多种花样)

0 引言 我们在信号测量、供电等应用场景时常会涉及到使用恒流源,以前觉得恒流源挺神奇的,研究了下实现方案,其实也没有多么高深(这里讨论的仅限于用在信号测量中的小电流恒流源设计),这里给出几个实用的恒流源电路设计方案。 1 恒流源电路设计 (1)使用三极管搭建的恒流源 (2)使用运放搭建的恒流源 (3)使用恒流二极管搭建的恒流源 pt100恒流源测温电路图_电子技术_电工之家 ...

数字世界 万物互联 9524

ONNX Runtime C# YOLO全链路压测:从300ms到22ms的15个底层优化技巧

摘要:本文分享了工业质检场景下C#调用YOLOv8s ONNX模型的性能优化实战经验。原始单帧推理耗时300ms无法满足产线需求,通过全链路分析定位瓶颈(预处理85ms、推理180ms、后处理30ms)。重点优化措施包括:使用OpenCVSharp CUDA加速预处理(85ms→12ms),开启ONNX Runtime ALL级别图优化,选用TensorRT执行提供程序(180ms→22ms),以及优化内存管理和线程调度。最终实现单帧总耗时22ms±2ms,GPU利用率提升至85%,完整满足产线120块板/

2601_94871597的博客 402

Spring Boot整合Zookeeper实现分布式锁

锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。分布式锁是控制 微服务集群 之间同步访问共享资源的一种方式。

weixin_74412978的博客 1626

硅电容的工艺结构原理及选型参数总结

硅电容,也称为硅质电容或硅二极管电容,是一种特殊的电容器。它利用硅二极管的结构来实现电容的功能。本文对硅电容的工作原理,结构特点,选型参数及设计注意事项进行总结。

fydar的博客 2329

Spring boot整合dubbo+zookeeper

下文将简述springboot整合dubbo+zookeeper实现api+provider+consumer模式,Api用于定于interface,provider和consumer依赖Api,provider实现api接口,consumer调用provider。对比api模块增加了qos-enable和qos-port两个属性,QoS是Dubbo提供的运维和管理功能,表示开启;当dubbo-api、dubbo-provider和dubbo-consumer都启动完成后,使用消费者接口访问。

qq_38527427的博客 1793

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

springboot整合zookeeper

文章目录springboot整合zookeeperzookeeper基础curator简介curator整合依赖配置类yml配置注册监听机制watches所有测试Controller结果展示新增/查看(具体代码在controller层)修改/删除(具体代码在controller层)事务(具体代码在controller层)监听使用分布式锁(具体代码在controller层)配置中心案例(没有代码)分布式唯一id springboot整合zookeeper zookeeper基础 curator简介 curat

admin522043032的博客 6006

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Spring Boot 整合 Zookeeper和Dubbo 的详解

DD

wang13145的博客 1289

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

如何用Spring Boot 整合Dubbo + Zookeeper 实现分布式

RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。基于SpringBoot项目整合Dubbo + Zookeeper 实现消费者消费服务提供者的服务消费者为订单模块。

xxxzzzqqq_的博客 1111

Dubbo ZooKeeper Spring Boot整合

Dubbo 是一款高性能的 Java RPC 框架,用于快速开发高性能的服务。

weixin_41562028的博客 1590

Spring Boot锦集(三):Spring Boot整合Kafka | Zookeeper/Kafka的安装和配置 | 总结的很详细

走前人走过的路,为后来者踩坑,带你避坑。 在整合的过程中,难免遇到磕磕碰碰,里面遇到的一些坑,基本都有标注。 本文对通过一个小案例,初步介绍了 Spring Boot对kafka的整合,完成了从Spring Boot中调用生产者(向kafka中创建主题)、消费者(消费信息)完成对kafka的调用。

血煞长虹 的专栏 5504

Spring Boot整合Dubbo+ZooKeeper

Autowired**注解用法是类似的,只是@Autowired注解是自动装配本地的服务,@DubboReference是远程引用服务提供者的服务。要使用服务提供者提供的服务,需要先从注册中心中获取服务,获取服务使用**@DubboReference**注解。使用**@DubboService**后,可以被扫描到,在项目已启动就自动注册到注册中心。服务,服务启动成功后,可以在Dubbo-Admin中看到消费者和提供者的服务调用关系。启动服务,服务启动成功后,可以在Dubbo-Admin中看到注册的服务。

null 1332
上一篇: Spring Boot整合阿里云存储OSS
下一篇: 设计模式--三种工厂模式
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值