关于后端:基于-Kyuubi-实现分布式-Flink-SQL-网关

<article class=“article fmt article-content”><blockquote><p>本文整顿自网易互娱资深开发工程师、Apache Kyuubi Committer 林小铂的《基于 Kyuubi 实现分布式 Flink SQL 网关》分享,内容次要分为以下四局部:</p><ol><li>Kyuubi 是什么</li><li>Kyuubi 架构设计</li><li>Flink x Kyuubi 劣势</li><li>将来瞻望</li></ol></blockquote><h2>一. Kyuubi 是什么</h2><h3>1.1. Kyuubi 简介</h3><p>简略来说,Kyuubi 是一个分布式、多租户的 SQL 网关。置信大家先会想到的问题是,Flink 曾经提供 SQL Gateway,为什么还须要 Kyuubi 呢?其实答案就是分布式和多租户两个关键词,两者相辅相成,Kyuubi 很多高级性能都是从分布式和多租户衍生而来的。</p><p></p><h3>1.2. Kyuubi 的倒退历程</h3><p></p><ul><li>2018-2020 0.x 版本</li></ul><p>Kyuubi 在 2018 年立项,最后目标次要为解决 Hive 用户迁徙到 Spark SQL (Spark Thrift Server) 的痛点,比方租户间隔离和服务稳定性的问题。2018-2020 年是 Kyuubi 的 0.x 版本阶段,这个期间次要定位为 Spark Thrift Server 的升级版,用户次要来自 Spark 社区。</p><ul><li>2020-2021 1.x 版本</li></ul><p>在 Kyuubi 倒退过程中,咱们逐步意识到 Kyuubi 解决的问题并不是 Spark 独有,而是不同引擎都会遇到的共性问题。于是 2021 年 Kyuubi 进行了架构降级,将通用解决方案形象成通用的 Kyuubi Server,而后对接不同引擎逻辑则成为 Kyuubi Engine。这是 Kyuubi 的 1.x 版本阶段,定位演变为通用的分布式多租户 SQL 网关。</p><ul><li>2021 Apache 孵化</li></ul><p>2021 年 9 月 Kyuubi 进入 Apache 孵化器,在 Flink 1.16 引入 SQL Gateway 后,Kyuubi Flink Engine 进行重构将底层改为基于 Flink SQL Gateway。</p><ul><li>2023 Apache TLP</li></ul><p>2023 年初 Kyuubi 从孵化器顺利毕业成为 Apache 顶级我的项目。</p><h3>1.3. 支流计算引擎发展趋势</h3><p></p><p>Kyuubi 的倒退历程和开源大数据的计算引擎发展趋势是密不可分的。</p><p>业界最早的开源计算引擎是 MapReduce,这时编程 API 是 Java 不反对 SQL,所以也没有 SQL 网关一说。</p><p>在 2014 年左右,随同着 SQL on Hadoop 潮流,Hive 代替 MapReduce 成为支流引擎。Hive 提供 Hive Server2 负责将 SQL 翻译成底层的 MapReduce,能够说是 SQL 网关的鼻祖。</p><p>后续 Spark 呈现,其内存计算性能比起 Hive 大大晋升,不少用户从 Hive 迁徙至 Spark。Spark 提供了SparkSQL 编程 API,而后对应的 SQL 服务组件为 Spark Thrift Server。</p><p>在最近几年,Flink 在实时计算和流批一体上的劣势又吸引不少用户从 Spark 或者 Hive 迁徙过去。Flink 提供 FlinkSQL,对应的 SQL 服务组件为 Flink SQL Gateway。</p><p>在这几轮技术浪潮中,每个引擎有本人的 SQL 服务组件(咱们能够统称他们为 SQL Gateway),但它们的性能其实并没有齐全对齐,很多企业级的个性是缺失的,而 Kyuubi 的指标则是作为对立标准化的 SQL 网关来屏蔽掉这些差别。</p><h3>1.4. SQL Gateway 比照</h3><p></p><p>上图是不同 SQL 网关的要害个性比照。</p><h4>1.4.1. 多租户</h4><p>多租户包含认证和资源隔离两个要害规范。</p><ul><li>在这方面,Hive Server 反对是最好的;</li><li>相对而言,Spark Thrift Server 因为自身会绑定一个 Spark 集群,而 Spark 集群是单用户的,所以仅能在 Driver 端做到 DDL 假装,而在集群端执行的 DQL 和 DML 其实都是以 Spark Thrift Server 自身的用户来执行的;</li><li>Flink SQL Gateway 则是受限于 Flink 自身不反对多租户;</li><li>最初是 Kyuubi,Kyuubi 是 Server 和 Engine 拆散的架构,所以至多能在引擎粒度反对多租户</li></ul><h4>1.4.2. 程度拓展和高可用</h4><p>程度拓展和高可用这两个个性通常和分布式的架构绑定,因而分布式架构的 Hive Server2 和 Kyuubi 都是反对的,而 Spark Thrift Server 和 Flink SQL Gateway 暂不反对。</p><h4>1.4.3. 动静资源配置</h4><ul><li>Hive Server 是能够在每条 SQL 的粒度上独自指定资源;</li><li>Spark Thrift Server 会绑定一个 Application,所以资源是全局的,集群资源在 Spark Thrift Server 启动时就曾经确定;</li><li>Flink SQL Gateway 没有和 Flink Cluster 强绑定,所以资源还是集群粒度的;</li><li>Kyuubi 能够在引擎粒度去执行资源。</li></ul><h4>1.4.4. 多版本能力</h4><p>SQL 网关能够承受一些低版本的 Client 的申请,但通常要求和集群的计算引擎的版本是保持一致的。这会导致降级集群版本的时候可能要开多个 SQL 网关的实例,Kyuubi 对这方面做了兼容解决。Kyuubi 的一个实例,是能够兼容多个版本的计算引擎。比方 Kyuubi 的最新版本 Flink Engine ,它兼容 Flink 1.16 到 1.18 三个版本。</p><h2>二. Kyuubi 的架构设计</h2><h3>2.1. Kyuubi 架构</h3><p></p><p>Kyuubi 从部署架构上分为 Kyuubi Client、Kyuubi Server 和 Kyuubi Engine 三层:</p><ul><li>Kyuubi Client 次要是将用户 SQL 提交给 Kyuubi Server。Client 能够是和 Hive 兼容的 Beeline 或者反对 JDBC 或者 REST 的任意客户端。</li><li>Kyuubi Server 负责 Session / Operation / Engine 的治理。Server 会接管 Client 连贯,并将申请通过 RPC 传递给 Engine 执行。</li><li>Kyuubi Engine 承载理论计算。Engine 会针对不同的引擎有对应的实现,比方 Flink Engine、Spark Engine、Trino Engine。Engine 个别会运行在引擎的 master 节点,对于 Spark 来说就是 Spark Driver,对 Flink 来说就是 JobManager。</li></ul><h3>2.2. Kyuubi 会话路由</h3><p></p><p>在 Kyuubi 架构中 Client 与 Server、Server 与 Engine 之间的通信均有基于 Zookeeper 的服务发现和负载平衡,这意味着不同模块之间是十分松耦合的。在同一个 Zookeeper namespace 下,Client 能够连到任意一个 Server 上, Server 也能拜访任意一个 Engine。</p><p>一个申请最终落到哪个 Engine 上由 Kyuubi Server 自动控制。Kyuubi Server 会依据多租户隔离策略的主动抉择一个适合的 Engine,如果满足要求的 Engine 不存在,那么 Kyuubi Server 会即时启动一个。绝对地,当一个 Engine 闲置一段时间后,Engine 会主动退出来节俭资源,当然也能够通过 Kyuubi Server 被动敞开 Engine。能够说 Kyuubi Engine 是按需启动的,而后生命周期也是由 Server 治理。</p><h3>2.3. Kyuubi 引擎隔离级别</h3><p></p><p>那么 Kyuubi Server 如何决定是否启动一个新的 Engine 呢?这很大水平上是由 Kyuubi 引擎隔离级别决定的。</p><p>Kyuubi 提供 4 种引擎隔离级别:</p><ul><li>CONNECTION 级别意味着每个连贯独占一个 Engine,这是最高的隔离级别,比拟适宜离线的大作业、Ad-hoc 查问或者实时作业的状况</li><li>USER 级别意味着每个用户独占一个 Engine,适宜大部分场景</li><li>GROUP 级别则是每个用户组共享一个 Engine,适宜小数据量的场景</li><li>SERVER 级别则是全副用户共享全局的一个 Engine,这是最低的隔离级别,个别是管理员执行治理操作时应用</li></ul><p>在引擎隔离级别之上,Kyuubi 还提供细粒度的路由设定,也就是 Subdomain。比方一个用户可能心愿用一个 Flink Engine 做实时计算,另外一个 Flink Engine 做 OLAP 查问。针对这种状况,Kyuubi 提供 subdomain 配置项。subdomain 容许在一个 namespace 再做划分。比方上述场景,用户能够别离在连贯时指定 kyuubi.engine.share.level.subdomain=realtime 或 kyuubi.engine.share.level.subdomain=olap ,这样 Kyuubi Server 就会启动两个 Flink Engine。</p><h3>2.4. Kyuubi Server 状态共享</h3><p></p><p>大部分状况下 Kyuubi Server 是没有状态的,但也会有例外。例如当用户批量提交大量的 SQL 到 Kyuubi,Kyuubi Server 会将申请放入队列,但这个队列是在内存的,其余 Kyuubi Server 实例并不知道这批申请。如果用户前后两个申请被路由到不同的 Kyuubi Server,那么可能会产生状态不统一的问题。用户可能会说我刚刚提交了一批作业,为什么当初查不到。</p><p>为此,Kyuubi 针对不同场景进行了优化。首先取决于 Client 类型,如果是基于 JDBC,JDBC 是长连贯比较稳定,所以个别不会出问题。但如果是基于 REST,那么都是 HTTP 短链接,负载均衡器很可能把申请路由到不同实例上。</p><p>Kyuubi 的解决方案是引入了数据库来长久化 Server 的状态,包含申请的内容、Server ID 和 Client ID。如果其余 Kyuubi Server 接管到不属于本人的申请,能够通过 REST Fronted 将申请转发给正确的 Kyuubi 实例。</p><h2>三. Flink x Kyuubi 劣势</h2><h3>3.1. 劣势一:分布式多租户</h3><p></p><p>这是 Kyuubi 的一个规范劣势:程度拓展、多租户、高可用、多版本和动静资源配置。</p><p>值得一提的是,在以前主打实时计算的背景下,其实 Flink 对 SQL 网关的需要不是很高,通常咱们可能单实例的 SQL 网关就能解决问题。</p><p>然而随着 Flink 往流批一体和 OLAP 的方向倒退,咱们对 SQL 网关的需要越来越高,无论是连接数还是申请量都有可能翻一个数量级,甚至两个数量级。那么这时 Kyuubi 分布式的解决方案就会成为一个必需品。</p><h3>3.2. 劣势二:优化 Application 模式</h3><p></p><p>Kyuubi 的 Flink Application 模式其实和规范的 Application 模式是有肯定差异的。Flink 是提供了四种部署的模式,能够分成两类:</p><ul><li>Session 和 Standalone 模式。这类是单集群能够运行多作业,然而集群的生命周期须要手动管控,须要在申请之前启动一个集群,不必了再手动关掉。</li><li>Application 和 PerJob 模式。这类是单集群只容许单作业,然而长处是集群的生命周期能够间接绑定作业的生命周期,作业完结集群就会退出,开释资源。</li></ul><p>以上这两类的部署模式是互有优缺点的。而 Kyuubi 的 Application 模式联合了两者的长处。它容许单集群多作业,而集群的生命周期由 Kyuubi 管控,用户是不必去操心的。为理解这点,咱们上面先简略回顾一下 Flink SQL 的翻译流程。</p><h4>3.2.1. Flink SQL 工作流程</h4><p></p><p>从用户提交的 Flink SQL 到变成 Flink Runtime 能够去执行的作业,会有一个 SQL 翻译的过程。这个过程能够分成四步。</p><ul><li>解析。用户提交的 SQL ,会被 Parser 解析成逻辑执行打算。</li><li>优化。逻辑执行打算会被 Optimizer 优化,生成物理执行打算。</li><li>编译。物理执行打算会被 Planner 编译成 Java 代码。</li><li>部署。 构建 JobGraph , 提交给 JobManager 。</li></ul><p>通常来说,这四步都会在一个 TableEnvironment外面去实现。</p><h4>3.2.2. Flink SQL Gateway PerJob 架构</h4><p></p><p>在 PerJob 架构下 Flink SQL Gateway 会在外部开启 TableEnvironment , SQL 翻译的四步全副做完后,生成 JobGraph 提交给 JobManager 。</p><p>这是很规范的一个应用制式,当然是没什么问题,当下 PerJob 的部署模式曾经过期了,咱们要迁徙到 Application 的模式下。</p><h4>3.2.3. Flink SQL Gateway Application 架构</h4><p></p><p>在规范的一个 Application 模式下,会要求用户的 main 函数在 JobManager 下来执行,那么这意味着SQL 翻译至多最初一步的部署,会在 JobManager 下来实现。</p><p>针对这个问题,社区提出一个计划 FLIP-316,就是 Flink SQL Gateway去反对 Application 的一个模式。在这个议案外面 Flink SQL Gateway 会在本地外部的 TableEnvironment 实现 SQL 翻译的前两步,也就是解析优化。生成两头的物理执行打算能够被序列化为 JsonPlan ,而后与其余资源文件一起提交给 JobManager ,JobManager 会启一个main 函数去实现编译和部署这两步。通过这种形式 Flink SQL Gateway 就能够去反对 Application 模式。</p><p>然而这个计划有一个毛病,就是 JsonPlan 目前是只反对 DML ,这意味着在一些 OLAP 场景,罕用的 Select 查问没有方法间接通过 Application 来反对。</p><h4>3.2.4. Kyuubi Flink Application 架构</h4><p></p><p>Kyuubi 的 Flink Application 架构模式是怎么解决这些问题的。</p><p>首先, Kyuubi 的 Flink Engine 是运行在 JobManager 外面的,它能够通过 RPC 的形式去接管到用户提交的 SQL ,他在外部的 Table Environment ,就能够像Flink SQL Gateway 里的 PerJob 模式,一次性实现上述四步工作。</p><p>最初失去的作业,通过 JobManager 外部的 Dispatcher API 去提交。通过这种形式就能够绕开 Application 模式下 JobManager 要求每个集群只有一个作业的限度,也没有 JsonPlan 带来的问题。</p><p>对于 JobManager 来说, Kyuubi Flink Engine相当于是始终在运行,没有退出的用户main函数。 Flink Engine 什么时候退出, JobManager 就会 Shutdown 把资源给开释掉。</p><h3>3.3. 劣势三:多引擎反对</h3><p></p><p>这能够分成对立入口和引擎插件两个方面。</p><h4>3.3.1. 对立入口</h4><ul><li>流批一体敌对,它能够作为一个多引擎的对立入口,这样不便不同引擎的相互之间迁徙。像从 Hive 、Spark 迁徙到流批一体的 Flink ,能够间接用 Kyuubi 来实现。如果是 Spark SQL 的用户,那很可能也是 Kyuubi 的用户,就只有新增一个 Flink Engine 就能够。</li><li>Kyuubi 能够做混合负载的复用网关,反对多种计算引擎,不须要为每一种计算引擎保护 SQL Gateway。</li><li>Kyuubi Server 能够作为对立平安认证的入口,它能够在认证结束当前把用户的凭证,比方 Kerberos TGT ,通过 RPC 形式传递给 Engine , 而后 Server 会负责定时 renew 凭证 。</li></ul><h4>3.3.2. 引擎插件</h4><p>另一方面,Kyuubi 提供灵便的插件机制反对满足平台治理需要,例如 SQL 血统提供、集成 Ranger 提供列级的访问控制或者监听事件。局部插件会依赖于引擎自身的反对,例如 Kyuubi Spark Engine 的血统提取是通过 Spark 提供的 QueryExecutionListener 接口实现,而 Flink 的血统反对也在 1.18 版本有了接口,后续 Kyuubi 这边也会跟进。</p><h3>3.4. 劣势四:可观测性</h3><p></p><p>Kyuubi 的 Metric 零碎是很欠缺的。</p><ul><li>Reporter 罕用的有 JMX 、 Prometheus 和打印到日志的 Log Reporter 。</li><li>Metric 纬度十分丰盛,包含 Connection 、 Operation 、 Server 的线程池、 Engine 的状态、不同RPC申请的时长、频率等等。</li></ul><p>同时,Kyuubi Server 提供内嵌的 Web UI,能够很直观的看到各项指标。</p><h2>四. 将来瞻望</h2><p></p><p>这是 Kyuubi 的 Flink Engine 的一些 Roadmap ,其中很多工作依赖 Flink 自身裸露的能力,须要两个社区独特推动。</p><ul><li>欠缺 on K8s 的 Flink Application 模式,这点其实和 Flink SQL Gateway 遇到的阻塞点是一样的,这点会依赖于 FLIP-316。</li><li>目前 Kyuubi 的 Application Mode 不足多作业的 JM HA 反对,这点咱们会推动社区去摸索解决方案。</li><li>Flink 引擎插件的反对,咱们会不断完善 Flink Engine 的插件反对,包含审计、血统等插件。</li><li>最初是 SQL 粒度的资源管理,目前 Flink 细粒度资源只反对 DataStream API,而 Flink SQL 只能通过调整并行度来设置资源,咱们会摸索把它裸露到 SQL API 的形式。</li></ul><h2>Flink Forward Asia 2023</h2><p>本届 Flink Forward Asia 更多精彩内容,可微信扫描图片二维码观看全副议题的视频回放及 FFA 2023 峰会材料!</p><p></p><h2>更多内容</h2><p></p><h2>流动举荐</h2><p>阿里云基于 Apache Flink 构建的企业级产品-实时计算 Flink 版现开启流动:<br/>59 元试用 实时计算 Flink 版(3000CU*小时,3 个月内)<br/>理解流动详情:https://free.aliyun.com/?pipCode=sc</p><p></p></article> ...

March 5, 2024 · 4 min · jiezi

关于后端:Docker容器实战00基础命令大全

<article class=“article fmt article-content”><h2>1 容器生命周期治理</h2><h3>1.1 docker start</h3><p>启动一或多个已被进行的容器。</p><pre><code class=“bash”># 启动已被进行的容器myrunoobdocker start myrunoob</code></pre><h3>1.2 docker stop</h3><p>进行一个运行中的容器</p><pre><code class=“bash”>docker stop myrunoob</code></pre><h3>1.3 docker restart</h3><p>重启容器</p><pre><code class=“bash”>docker restart myrunoob</code></pre><h3>1.4 docker run</h3><p>创立一个新的容器并运行一个命令。</p><p>要依据 <code>docker images</code> 命令的后果启动对应镜像的容器,执行:</p><ol><li>运行 <code>docker images</code> 命令查看以后零碎中所有可用的镜像列表。</li><li>从后果中找到您想要启动的镜像的 <code>REPOSITORY</code> 和 <code>TAG</code>。</li><li>应用 <code>docker run</code> 命令启动一个新的容器。该命令的根本格局为 <code>docker run [OPTIONS] IMAGE [COMMAND] [ARG…]</code>。其中 <code>IMAGE</code> 是镜像的名称,可能包含 <code>TAG</code>(如果未指定,则默认为 <code>latest</code>)。</li></ol><p>案例:</p><ol><li>查看镜像列表:</li></ol><pre><code class=“sh”>docker images</code></pre><p>输入:</p><pre><code class=“bash”>REPOSITORY TAG IMAGE ID CREATED SIZEubuntu 18.04 c3c304cb4f22 2 weeks ago 64.2MBnginx latest 9beeba249f3e 3 weeks ago 109MB</code></pre><p>启动名为 <code>nginx</code> 的镜像:</p><pre><code class=“sh”>docker run -d -p 8080:80 –name mynginx nginx</code></pre><p>在这个例子中:</p><ul><li><code>-d</code> 选项示意在后盾运行容器。</li><li><code>-p 8080:80</code> 示意将容器的 80 端口映射到主机的 8080 端口。</li><li><code>–name mynginx</code> 为您的容器设置了一个名字 <code>mynginx</code>,不便当前援用。</li><li><code>nginx</code> 是您抉择的镜像名称。</li></ul><p>如果您须要应用特定的标签,能够将其附加到镜像名称前面,例如 <code>nginx:1.17</code>。</p><p>依据具体需要增加或批改命令行选项,如需在容器启动时执行特定的命令或传递环境变量等。</p><p>实例:</p><pre><code class=“bash”>docker run -p 6379:6379 –name redis # 将主机上的 /home/redis6/data 目录挂载到容器外部的 /data 目录,以便能够将 Redis 数据长久化到主机-v /home/redis6/data:/data # 将主机上的 /home/redis6/conf/redis.conf 文件挂载到容器外部的 /etc/redis/redis.conf 文件,以便能够应用自定义的 Redis 配置文件-v /home/redis6/conf/redis.conf:/etc/redis/redis.conf # 指定要应用的 Redis 镜像及版本号,并在后盾运行容器-d redis:6.2.7 # 在容器外部执行的命令,启动 Redis 服务,并应用 /etc/redis/redis.conf 配置文件redis-server /etc/redis/redis.conf</code></pre><pre><code class=“bash”>-a stdin 指定规范输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;-d 后盾运行容器,并返回容器ID;-i:–interactive 以交互模式运行容器,通常与 -t 同时应用,即便未连贯STDIN也放弃关上状态-P: 随机端口映射,容器外部端口随机映射到主机的端口-p: 指定端口映射,格局为:主机(宿主)端口:容器端口-t: –tty Allocate a pseudo-TTY为容器重新分配一个伪输出终端,通常与 -i 同时应用;–name=“nginx-lb” 为容器指定一个名称–dns 8.8.8.8: 指定容器应用的DNS服务器,默认和宿主统一;–dns-search example.com: 指定容器DNS搜寻域名,默认和宿主统一;-h “mars”: 指定容器的hostname;-e username=“ritchie”: 设置环境变量;–env-file=[]: 从指定文件读入环境变量;–cpuset=“0-2” or –cpuset=“0,1,2”: 绑定容器到指定CPU运行;-m :设置容器应用内存最大值;–net=“bridge”: 指定容器的网络连接类型,反对 bridge/host/none/container–link=[]: 增加链接到另一个容器;–expose=[]: 凋谢一个端口或一组端口;–volume , -v: 绑定一个卷# 设置容器的重启策略为 always,只能在 Docker 1.2 或更高版本中应用–restart=always</code></pre><h2>2 本地镜像治理(镜像操作命令)</h2><h3>2.1 image</h3><pre><code class=“bash”># 列出本机所有 image 文件$ docker image ls</code></pre><pre><code class=“bash”># 删除 image 文件$ docker image rm [imageName]</code></pre><h4>实战</h4><pre><code class=“bash”>[root@scheduler-center-1 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESfb88be2a8283 xuxueli/xxl-job-admin:2.4.0 “sh -c ‘java -jar $J…” 15 hours ago Up 15 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp xxl-job-admin[root@scheduler-center-1 ~]# docker image rm xxl-job-adminError response from daemon: No such image: xxl-job-admin:latest[root@scheduler-center-1 ~]# docker rm xxl-job-adminError response from daemon: You cannot remove a running container fb88be2a828361ed7173d94a346a7c7c2a4aa11bb17d82450a4424ddf44651f0. Stop the container before attempting removal or force remove[root@scheduler-center-1 ]# docker rm xuxueli/xxl-job-admin:2.4.0Error response from daemon: No such container: xuxueli/xxl-job-admin:2.4.0</code></pre><p>试图删除 Docker 容器和 Docker 镜像,但遇到报错:</p><ol><li><p><strong>删除容器时报错:</strong></p><pre><code class=“bash”>docker rm xxl-job-admin</code></pre><p>错误信息:You cannot remove a running container fb88be2a8283… Stop the container before attempting removal or force remove</p><p>起因:你不能删除正在运行的容器。在这种状况下,容器 “fb88be2a8283” 处于运行状态。</p><p>解决办法:首先进行容器,而后再删除。进行容器:</p><pre><code class=“bash”>docker stop xxl-job-admin</code></pre><p>而后再尝试删除容器。</p></li><li><p><strong>删除镜像时报错:</strong></p><pre><code class=“bash”>docker image rm xxl-job-admin</code></pre><p>错误信息:Error response from daemon: No such image: xxl-job-admin:latest</p><p>起因:Docker 引擎无奈找到名为 “xxl-job-admin” 的镜像,可能是因为该镜像不存在或者被命名为 “xuxueli/xxl-job-admin:2.4.0”。</p><p>解决办法:确保要删除的镜像名称是正确的。如果你要删除 “xuxueli/xxl-job-admin:2.4.0”,则应该应用如下命令:</p><pre><code class=“bash”>docker image rm xuxueli/xxl-job-admin:2.4.0</code></pre></li></ol><h4>image inspect</h4><p>查看 Docker 镜像详细信息:</p><pre><code class=“bash”>[root@service-monitoring ]# docker image inspect mysql:5.7.42-oracle | grep -i version “GOSU_VERSION=1.16”, “MYSQL_VERSION=5.7.42-1.el7”, “MYSQL_SHELL_VERSION=8.0.33-1.el7” “DockerVersion”: “20.10.23”, “GOSU_VERSION=1.16”, “MYSQL_VERSION=5.7.42-1.el7”, “MYSQL_SHELL_VERSION=8.0.33-1.el7”</code></pre><p>有时可用于查看 lastest 标签的 image,版本号到底多少。</p><p>而 <code>docker inspect</code> 命令是用于查看 Docker 对象(如容器、镜像、网络等)的详细信息,它不仅能够查看镜像的元数据,还能够查看容器的元数据、网络的元数据等。</p><p>image文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样能够应用。为节省时间,尽量应用他人制作好的 image 文件。即便定制,也应基于他人的 image 文件进行加工,而不是从0开始。</p><p>为不便共享,image 文件制作实现后,上传到仓库:</p><ul><li>Docker 官网仓库 Docker Hub 是最重要、最罕用的 image 仓库</li><li>发售本人制作的 image 文件也可</li></ul><h3>2.2 images</h3><pre><code class=“bash”>docker images = docker image ls</code></pre><p>列出以后零碎所有可用 Docker 镜像。提供repository、tag、image ID、和size的摘要信息。可查看在本地机器下载或创立的镜像。</p><p></p><p><code>docker image</code> 和 <code>docker images</code> 区别:</p><ul><li><code>docker image</code> 命令是 Docker 17.06 版本后新增命令,用于治理 Docker 镜像。可用来列出本地镜像、删除本地镜像、构建镜像等操作。如应用 <code>docker image ls</code> 命令能够列出本地所有的镜像</li><li><code>docker images</code> 命令是晚期版本的 Docker 命令,用于列出本地所有镜像。性能与 <code>docker image ls</code>完全相同,只是命令不同</li></ul><h3>2.3 rmi</h3><p>不想要某 image 时可用。</p><p>等效命令:</p><pre><code class=“bash”>docker rmi imageId</code></pre><h3>2.4 tag</h3><h3>docker image build</h3><p>从Dockerfile构建image</p><pre><code class=“bash”>Usage: docker image build [OPTIONS] PATH | URL | -</code></pre><h3>history</h3><pre><code class=“bash”>docker history image_id</code></pre><p></p><h3>docker save</h3><p>可将Docker镜像保留成tar文件,不便在不同环境中迁徙和分享镜像。</p><pre><code class=“bash”>docker save # OPTIONS为可选参数 [OPTIONS] # IMAGE为须要导出的Docker镜像的名称(能够是多个) IMAGE [IMAGE…]</code></pre><p>如:</p><pre><code class=“bash”># 将myimage镜像保留为名为myimage.tar的tar文件,并指定了输入门路为/path/to/。docker save -o /path/to/myimage.tar myimage</code></pre><pre><code class=“bash”>-o, –output string:指定输入的压缩文件(.tar或.tgz)门路和名称-q, –quiet:静默模式,只输入错误信息和进度条–tag string:指定要导出的镜像的tag名称</code></pre><p>运行这个命令之前,要先应用docker pull命令下载须要导出的镜像。</p><h3>docker load</h3><h3>docker import</h3><h2>3 container</h2><h3>3.1 容器文件</h3><p>image 文件生成的容器实例,自身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件:</p><ul><li>image 文件</li><li>容器文件</li></ul><p>敞开容器并不会删除容器文件,仅是容器进行运行。</p><h3>docker container ls</h3><pre><code class=“bash”># 列出本机正在运行的容器[root@scheduler-center-1 ]# docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESfb88be2a8283 xuxueli/xxl-job-admin:2.4.0 “sh -c ‘java -jar $J…” 16 hours ago Up 16 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp xxl-job-admin</code></pre><pre><code class=“bash”># 列出本机所有容器,包含终止运行的容器docker container ls –all(-a)</code></pre><p>输入后果包含容器 ID。很多中央都要提供这 ID,如上一节终止容器运行的docker container kill命令。</p><blockquote>有人说 docker ps & docker ps -a 更不便查看 container 运行状态呀!因为 docker container options 是Docker 1.13中的更新,docker container ls 与 docker ps 性能雷同,但语义更明确,简化Docker用法,更举荐新写法。</blockquote><p><code>-q</code>间接显示以后所有容器的 container id</p><pre><code class=“bash”>docker container ls -aqdocker container ls -a | awk {‘print$1’}</code></pre><p></p><p>过滤状态字段显示</p><pre><code class=“bash”>docker container ls -f “status=exited”</code></pre><p></p><h3>docker container rm</h3><p>终止运行的容器文件,仍然会占据硬盘空间,能够应用docker container rm命令删除。</p><pre><code class=“bash”>docker container rm [containerID]</code></pre><p>运行下面的命令之后,再应用<code>docker container ls -a</code>命令,就会发现被删除的容器文件曾经隐没了。</p><h4>全副删除</h4><p>因为一个个指定 containerid 很麻烦,能够全副删除:</p><pre><code class=“bash”>docker rm $(docker container ls -aq)</code></pre><h4>条件过滤删除</h4><p>比方,咱们想把退出的给全副删除<br/></p><ul><li>筛选出退出状态的image 文件<br/><br/>间接删除</li></ul><pre><code class=“bash”>docker rm $(docker container ls -f “status=exited” -q)</code></pre><h3>docker container commit</h3><p>依据容器的更改创立新image,比方在原 image 根底上装置了新的软件,那就能够上传新 image。</p><pre><code class=“bash”>Usage: docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]</code></pre><p></p><p>可简写为</p><pre><code class=“bash”>docker commit</code></pre><h2>4 容器操作命令</h2><h3>4.1 ps</h3><p><code>docker ps</code> ,用于列出以后正在运行的容器的命令。它能够显示容器的 ID、名称、状态、启动工夫、所应用的镜像等信息。</p><p>如果在命令行中执行 <code>docker ps</code>,会输入以后正在运行的容器的列表,包含容器的 ID、名称、状态、启动工夫、所应用的镜像等信息。例如:</p><pre><code class=“bash”>CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESec88509b8b1b mysql:5.7.42-oracle “docker-entrypoint.s…” 10 minutes ago Up 10 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql</code></pre><p>下面的输入示意只有一个名为 <code>mysql</code> 的容器正在运行,它应用的是 <code>mysql:5.7.42-oracle</code> 镜像,并且将其 3306 端口映射到主机的 3306 端口。</p><pre><code class=“bash”>[root@service-monitoring home]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESec88509b8b1b mysql:5.7.42-oracle “docker-entrypoint.s…” 10 minutes ago Exited (1) 10 minutes ago mysql60180275418c hello-world “/hello” 2 days ago Exited (0) 2 days ago laughing_mcclintock[root@service-monitoring home]# </code></pre><h3>4.2 inspect</h3><p>docker inspect : 获取容器/镜像的元数据。</p><pre><code class=“bash”>docker inspect [OPTIONS] NAME|ID [NAME|ID…]</code></pre><pre><code class=“bash”>-f :指定返回值的模板文件。-s :显示总的文件大小。–type :为指定类型返回JSON。</code></pre><pre><code class=“bash”># 获取镜像mysql:5.6的元信息runoob@runoob:$ docker inspect mysql:5.6[ { “Id”: “sha256:2c0964ec182ae9a045f866bbc2553087f6e42bfc16074a74fb820af235f070ec”, “RepoTags”: [ “mysql:5.6” ], “RepoDigests”: [], “Parent”: “”, “Comment”: “”, “Created”: “2016-05-24T04:01:41.168371815Z”, “Container”: “e0924bc460ff97787f34610115e9363e6363b30b8efa406e28eb495ab199ca54”, “ContainerConfig”: { “Hostname”: “b0cf605c7757”, “Domainname”: “”, “User”: “”, “AttachStdin”: false, “AttachStdout”: false, “AttachStderr”: false, “ExposedPorts”: { “3306/tcp”: {} },…</code></pre><p>获取正在运行的容器mymysql的 IP。</p><pre><code class=“bash”>runoob@runoob:$ docker inspect –format=’{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ mymysql172.17.0.3</code></pre><h3>pull</h3><p></p><h3>push</h3><pre><code class=“bash”>docker push</code></pre><p><br/>留神 tag 必须是 hub 仓库的用户名,否则报错无权限。<br/><br/>但不举荐间接上传镜像,而是思考平安问题,应用 Dockerfile 文件。即建设 hub 仓库和 GitHub 的映射,只有 GitHub 上有 Dockerfile 就会主动映射到 Dockerhub。</p><h3>docker search</h3><p><code>docker search</code>命令用于在Docker Hub上搜寻能够用来构建和运行容器的镜像。能够依照以下格局应用该命令:</p><pre><code class=“bash”>docker search [OPTIONS] # TERM是须要搜寻的关键字 TERM</code></pre><p>如:</p><pre><code class=“bash”>docker search portainer</code></pre><p>下面的命令会在Docker Hub上搜寻关键字为<code>portainer</code>的镜像,并列出匹配的相干信息,如镜像名称、形容、星级、官网/非官方等。</p><p></p><p>罕用选项:</p><pre><code class=“bash”>–filter=STARS=N:示意只列出点赞数大于或等于N的镜像–filter=IS_OFFICIAL=true|false:示意只列出Docker官网公布的或者非官方公布的镜像-s, –stars[0]:示意按点赞数排序,默认值为1,即只显示点赞数大于等于1的镜像–format="{{.Name}}:{{.Description}}":自定义输入格局,例如仅显示镜像名称和形容信息</code></pre><p><code>docker search</code>命令不仅能用来搜寻公共仓库,还能够搜寻公有仓库,只须要在关键字中蕴含公有仓库地址即可,如:</p><pre><code class=“bash”>docker search docker.example.com/mysql</code></pre><p>因为网络起因,<code>docker search</code>命令可能会存在拜访异样或者网络超时等问题。</p><h3>docker exec</h3><p>用于在运行中的容器中执行命令。容许你在容器内执行命令,就像在本地计算机一样:</p><ul><li>对在运行中的容器中调试应用程序很有用</li><li>或在容器中运行交互式命令行工具</li></ul><pre><code class=“bash”>docker exec# OPTIONS 参数可选,能够用于指定一些选项,例如执行命令的用户、工作目录等 [OPTIONS] # CONTAINER 参数必须,指定要在其中执行命令的容器 CONTAINER # COMMAND 和 ARG 参数也必须,指定要在容器外部执行的命令及其参数 COMMAND [ARG…]</code></pre><pre><code class=“bash”># 进个 py 我的项目的容器docker exec -it image_id /bin/bash# 查看 Python 的过程ps -ef | grep python# 进入容器我的项目的pythondocker exec -it image_id python# 查看 ipdocker exec -it image_id ip a[root@service-monitoring ]# docker exec -it mysql bashbash-4.2# mysql -u root -pEnter password: Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 5Server version: 5.7.42 MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.mysql> </code></pre><h3>docker update</h3><p>更新正在运行的容器的配置信息。可用于更新容器的 CPU、内存、网络、挂载卷等配置信息,而无需进行和重启容器。</p><pre><code class=“bash”>docker update [OPTIONS] CONTAINER [CONTAINER…]–cpu-shares:设置容器应用 CPU 的绝对权重。默认为 0,示意与其余容器共享 CPU 工夫–memory:设置容器应用的内存限度。默认为 0,示意不限度内存应用–restart:设置容器退出后的重启策略。默认为 “no”,示意容器退出后不重启–ulimit:设置容器应用的系统资源限度,如最大关上文件数、最大过程数等</code></pre><p>如将容器 <code>mycontainer</code> 的 CPU 权重设为 512,内存限度为 1GB,重启策略为 always:</p><pre><code class=“bash”>docker update –cpu-shares 512 –memory 1g –restart always mycontainer</code></pre><p>该命令只能更新容器的配置信息,不能更新容器的镜像和文件系统。如果须要更新镜像和文件系统,须要先进行容器,而后应用 <code>docker rm</code> 命令删除容器,再应用 <code>docker run</code> 命令从新创立容器。</p><h2>5 Docker-Compose</h2><p>该系列命令须运行在 yaml文件所在目录。否则报错:</p><pre><code class=“bash”>[root@javaedge-monitor-platform-dev ]# docker-compose exec mysql bashERROR: Can’t find a suitable configuration file in this directory or any parent. Are you in the right directory? Supported filenames: docker-compose.yml, docker-compose.yaml</code></pre><h3>docker compose</h3><p>docker compose up [-d]</p><pre><code class=“bash”># 应用 docker-compose.yml 文件定义的容器,启动并在后盾运行。docker compose # 创立容器并启动 up # 后盾运行形式启动 -d</code></pre><p>容器启动后会始终在后盾运行,可通过 <code>docker-compose ps</code> 查看状态。</p><p>要进行后盾运行的容器,能够应用 <code>docker-compose stop</code> 命令。</p><h2>6 network</h2><p>Docker network 相干的常用命令次要包含:</p><ol start=“3”><li><code>docker network create</code> - 创立一个新网络</li><li><code>docker network connect</code> - 将容器连贯到网络</li><li><code>docker network disconnect</code> - 将容器从网络断开</li><li><code>docker network rm</code> - 删除指定网络</li></ol><h3>6.1 docker network ls</h3><p>列出 Docker 主机上的所有网络,包含网络名称、ID、驱动等信息。</p><pre><code class=“bash”>docker network ls</code></pre><h3>6.2 docker network inspect</h3><p>查看指定网络的具体配置信息。通过 network ID 或 name 指定网络:</p><pre><code class=“bash”>docker@minikube:$ docker network inspect bridge[ { “Name”: “bridge”, “Id”: “675eddaf1c1e76a5c0fe4b56f86831cb7c7d0fc597d766fd7df533cf09e11832”, “Created”: “2023-05-10T15:05:28.409718304Z”, “Scope”: “local”, “Driver”: “bridge”, “EnableIPv6”: false, “IPAM”: { “Driver”: “default”, “Options”: null, “Config”: [ { “Subnet”: “172.17.0.0/16”, “Gateway”: “172.17.0.1” } ] }, “Internal”: false, “Attachable”: false, “Ingress”: false, “ConfigFrom”: { “Network”: "" }, “ConfigOnly”: false, “Containers”: {}, “Options”: { “com.docker.network.bridge.default_bridge”: “true”, “com.docker.network.bridge.enable_icc”: “true”, “com.docker.network.bridge.enable_ip_masquerade”: “true”, “com.docker.network.bridge.host_binding_ipv4”: “0.0.0.0”, “com.docker.network.bridge.name”: “docker0”, “com.docker.network.driver.mtu”: “1500” }, “Labels”: {} }]docker@minikube:$ </code></pre><ol start=“3”><li><code>docker network create</code>创立一个新的 Docker 网络。咱们能够指定网络类型、驱动程序等配置创立定制化网络:</li></ol><pre><code class=“bash”>docker network create -d macvlan \ –subnet=172.16.86.0/24 \ –gateway=172.16.86.1 \ -o parent=eth0 pub_net</code></pre><ol start=“4”><li><code>docker network connect</code>将一个容器连贯到指定网络。需指定网络名称或 ID,以及容器名称或 ID:</li></ol><pre><code class=“bash”> docker network connect multi-host-network container1</code></pre><ol start=“5”><li><code>docker network disconnect</code>将容器从指定网络断开连接。应用办法与 <code>connect</code> 相似:</li></ol><pre><code class=“bash”>docker network disconnect multi-host-network container1</code></pre><ol start=“6”><li><code>docker network rm</code>删除指定的 Docker 网络。删除前,确保指定网络下没有任何容器在应用:</li></ol><pre><code class=“bash”>docker network rm multi-host-network </code></pre><p>所以,总结来说,Docker network 命令用于治理 Docker 的网络性能。咱们能够创立各种类型的网络,将容器连贯或断开网络,以及在须要时删除网络。熟练掌握 Docker 的网络性能和相干命令,能够让咱们在应用 Docker 部署利用时,有更高的灵活性和便捷性。适当应用网络能够实现容器间通信、容器到宿主机通信等,这在日常开发和运维场景下十分罕用。</p><pre><code class=“bash”>[root@javaedge-monitor-platform-dev docker]# docker network lsNETWORK ID NAME DRIVER SCOPE64ad1eca60f7 bridge bridge local4689aefb8f9b docker_my-bridge bridge localf2f555bed377 host host locald02380dd3da4 none null local[root@javaedge-monitor-platform-dev docker]# </code></pre><h2>7 日志 docker logs</h2><p>获取容器的日志。</p><h3>7.1 语法</h3><pre><code class=“bash”>docker logs [OPTIONS] CONTAINER</code></pre><ul><li><strong>-f :</strong> 跟踪日志输入</li><li><strong>–since :</strong>显示某个开始工夫的所有日志</li><li><strong>-t :</strong> 显示工夫戳</li><li><strong>–tail :</strong>仅列出最新N条容器日志</li></ul><h3>7.2 实例</h3><p>跟踪查看容器mynginx的日志输入。</p><pre><code class=“bash”>runoob@runoob:$ docker logs -f mynginx192.168.239.1 - - [10/Jul/2016:16:53:33 +0000] “GET / HTTP/1.1” 200 612 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36” “-“2016/07/10 16:53:33 [error] 5#5: *1 open() “/usr/share/nginx/html/favicon.ico” failed (2: No such file or directory), client: 192.168.239.1, server: localhost, request: “GET /favicon.ico HTTP/1.1”, host: “192.168.239.130”, referrer: “http://192.168.239.130/“192.168.239.1 - - [10/Jul/2016:16:53:33 +0000] “GET /favicon.ico HTTP/1.1” 404 571 “http://192.168.239.130/” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36” “-“192.168.239.1 - - [10/Jul/2016:16:53:59 +0000] “GET / HTTP/1.1” 304 0 “-” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36” “-”…</code></pre><p>查看容器mynginx从2016年7月1日后的最新10条日志。</p><pre><code class=“bash”>docker logs –since=“2016-07-01” –tail=10 mynginx</code></pre><h4>7.3 无奈查找指定字符串</h4><p>执行以下命令没有在docker logs的后果中查找字符串,而是会输入了所有的日志</p><pre><code class=“bash”>docker logs nginx | grep 127</code></pre><p>因为管道符仅对stdout无效,如果容器将日志记录到stderr,这种状况就会产生。</p><h4>解决方案</h4><p>把stderr重定向到stdout:</p><pre><code class=“bash”>docker logs nginx 2>&1 | grep 127</code></pre><p>还有一种形式,但麻烦:</p><pre><code class=“bash”>grep 127 docker inspect --format={{.LogPath}} nginx</code></pre><p>docker-compose可间接应用内置命令:</p><pre><code class=“bash”>docker-compose logs nginx | grep 127</code></pre><h2>8 docker scout quickview</h2><pre><code class=“bash”>docker scout quickview [IMAGE|DIRECTORY|ARCHIVE]</code></pre><p><code>docker scout quickview</code> 显示指定image的疾速概览。它显示指定image和根底image中破绽的摘要。如果可用,它还显示根底image的刷新和更新倡议。</p><p>如果没有指定image,则应用最近构建的image。</p><p>反对以下类型的构件:</p><ul><li>image</li><li>OCI 布局目录</li><li>由 <code>docker save</code> 创立的 Tarball 存档</li><li>本地目录或文件</li></ul><p>默认状况下,该工具冀望一个image援用,如:</p><ul><li><code>redis</code></li><li><code>curlimages/curl:7.87.0</code></li><li><code>mcr.microsoft.com/dotnet/runtime:7.0</code></li></ul><p>如要剖析的构件是 OCI 目录、Tarball 存档、本地文件或目录,或者如果您想要管制从何处解析图像,须在援用前加上以下之一:</p><ul><li><code>image://</code>(默认)应用本地图像,或者回退到注册表查找</li><li><code>local://</code> 应用本地图像存储中的图像(不进行注册表查找)</li><li><code>registry://</code> 应用注册表中的图像(不应用本地图像)</li><li><code>oci-dir://</code> 应用 OCI 布局目录</li><li><code>archive://</code> 应用由 <code>docker save</code> 创立的 Tarball 存档</li><li><code>fs://</code> 应用本地目录或文件</li></ul><h3>[选项]</h3><table><thead><tr><th>选项</th><th>短格局</th><th>默认值</th><th>形容</th></tr></thead><tbody><tr><td><code>–env</code></td><td> </td><td> </td><td>环境名称</td></tr><tr><td><code>–latest</code></td><td> </td><td> </td><td>最新索引的图像</td></tr><tr><td><code>–org</code></td><td> </td><td> </td><td>Docker 组织的命名空间</td></tr><tr><td><code>–output</code></td><td><code>-o</code></td><td> </td><td>将报告写入文件</td></tr><tr><td><code>–platform</code></td><td> </td><td> </td><td>要剖析的图像平台</td></tr><tr><td><code>–ref</code></td><td> </td><td> </td><td>如果提供的 Tarball 蕴含多个援用,则要应用的援用。仅实用于存档。</td></tr><tr><td><code>–stream</code></td><td> </td><td> </td><td>已弃用,流的名称</td></tr></tbody></table><h3>[示例]</h3><pre><code class=“bash”># 对image进行疾速概览$ docker scout quickview nacos/nacos-server:latest</code></pre><p></p><pre><code class=“bash”># 对最近构建的image进行疾速概览javaedge@JavaEdgedeMac-mini % docker scout qvINFO New version 1.2.2 available (installed version is 0.20.0) ✓ SBOM of image already cached, 450 packages indexed Your image nacos/nacos-server:latest │ 0C 4H 19M 22L Base image centos:7 │ 1C 13H 29M 13LWhat’s Next? Learn more about vulnerabilities → docker scout cves nacos/nacos-server:latest</code></pre><pre><code class=“bash”># 剖析软件构件的破绽。如未指定image,则应用最近构建的图像。javaedge@JavaEdgedeMac-mini frp_0.52.3 % docker scout cves nacos/nacos-server:latestINFO New version 1.2.2 available (installed version is 0.20.0) ✓ Provenance obtained from attestation ✓ SBOM of image already cached, 450 packages indexed ✗ Detected 20 vulnerable packages with a total of 44 vulnerabilities 0C 1H 5M 0L lxml 3.2.1pkg:pypi/lxml@3.2.1 ✗ HIGH CVE-2021-43818 [Improper Neutralization of Special Elements in Output Used by a Downstream Component (‘Injection’)] https://scout.docker.com/v/CVE-2021-43818 Affected range : <4.6.5 Fixed version : 4.6.5 CVSS Score : 8.2 CVSS Vector : CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:H/A:N</code></pre><h2>X help</h2><pre><code class=“bash”>docker –help</code></pre><p>遗记命令咋办?用它!</p><p><strong>关注我,紧跟本系列专栏文章,咱们下篇再续!</strong></p><blockquote><p>作者简介:魔都技术专家兼架构,多家大厂后端一线研发教训,各大技术社区头部专家博主,编程严选网创始人。具备丰盛的引领团队教训,深厚业务架构和解决方案的积攒。</p><p>负责:</p><ul><li>地方/分销预订零碎性能优化</li><li>流动&优惠券等营销中台建设</li><li><p>交易平台及数据中台等架构和开发设计</p><p>目前主攻升高软件复杂性设计、构建高可用零碎方向。</p></li></ul></blockquote><p>参考:</p><ul><li>编程严选网</li><li><p>https://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html</p><blockquote>本文由博客一文多发平台 OpenWrite 公布!</blockquote></li></ul></article> ...

March 5, 2024 · 7 min · jiezi

关于后端:linq-入门介绍更加优雅的流式集合处理

<article class=“article fmt article-content”><h2>拓展浏览</h2><blockquote><p>linq</p><p>querydsl</p></blockquote><h2>LINQ</h2><p>术语“LINQ to Objects”指间接将 LINQ 查问与任何 <code>IEnumerable<T></code> 汇合一起应用。 </p><p>能够应用 LINQ 来查问任何可枚举的汇合,例如 Primitive Array、Object Array、 List、 Collection 或 Iterable 等等。 </p><p>该汇合能够是用户定义的汇合,也能够是由 Java 开发包 API 返回的汇合。</p><p>从根本上说,“LINQ to Objects”示意一种新的解决汇合的办法。 采纳 LINQ 办法,只需编写形容要检索的内容的申明性代码。</p><h3>个性</h3><ul><li>实现了 LINQ to Objects 的所有 API。</li><li>反对更多 API 和元组。</li><li>反对 IEnumerable 和 Stream 相互转换。</li><li>反对 Android。</li></ul><h2>入门例子</h2><h3>Maven</h3><pre><code class=“xml”><dependency> <groupId>com.bestvike</groupId> <artifactId>linq</artifactId> <version>6.0.0</version></dependency></code></pre><h3>用法</h3><p>如果应用 java 8 或 java 9,倡议用 lombok.var 或 lombok.val 代替简单的返回类型。 </p><p>如果应用 java 10 或更高版本,倡议应用 var 代替简单的返回类型。</p><p>拼接不为空的字符串。</p><pre><code class=“java”>String result = Linq.of("!@#$%^", “C”, “AAA”, “”, “Calling Twice”, “SoS”, Empty) .where(x -> x != null && x.length() > 0) .aggregate((x, y) -> x + “, " + y);System.out.println(result);—-!@#$%^, C, AAA, Calling Twice, SoS</code></pre><p>判断所有的负数是否全副为偶数。</p><pre><code class=“java”>boolean result = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345) .where(x -> x > 0) .all(x -> x % 2 == 0);System.out.println(result);—-false</code></pre><p>判断所有的负数是否存在任一偶数。</p><pre><code class=“java”>boolean result = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345) .where(x -> x > 0) .any(x -> x % 2 == 0);System.out.println(result);—-true</code></pre><p>在开端追加一个数字并在头部插入两个数字。</p><pre><code class=“java”>String result = Linq.range(3, 2).append(5).prepend(2).prepend(1).format();System.out.println(result);—-[1, 2, 3, 4, 5]</code></pre><p>计算整数序列的平均值。</p><pre><code class=“java”>double result = Linq.of(5, -10, 15, 40, 28).averageInt();System.out.println(result);—-15.6</code></pre><p>连贯两个整数序列。</p><pre><code class=“java”>String result = Linq.of(1, 2).concat(Linq.of(3, 4)).format();System.out.println(result);—-[1, 2, 3, 4]</code></pre><h2>参考资料</h2><p>https://github.com/timandy/linq</p><blockquote>本文由博客一文多发平台 OpenWrite 公布!</blockquote></article> ...

March 5, 2024 · 1 min · jiezi

关于后端:jinq-入门介绍java中编写数据库查询的简单自然的方式

<article class=“article fmt article-content”><h2>拓展浏览</h2><blockquote><p>linq</p><p>querydsl</p></blockquote><h2>Jinq 是什么?</h2><p>Jinq为开发者提供了一种在Java中编写数据库查问的简略天然的形式。</p><p>你能够像解决存储在汇合中的一般Java对象一样解决数据库数据。你能够应用一般的Java命令遍历和过滤它们,而你的所有代码都将主动转化为优化的数据库查问。</p><p>最初,Java终于有了LINQ格调的查问!</p><p>简略天然的查问。</p><p>应用Jinq,你能够应用简略天然的Java语法编写数据库查问。利用Java 8对函数式编程的新反对,你能够应用与惯例Java数据雷同的代码来过滤和转换数据库中的数据。</p><p>例如,上面是一段应用Jinq从数据库中获取所有名为“Alice”的客户的Java代码。</p><pre><code class=“java”>database.customerStream().where(customer -> customer.getName().equals(“Alice”));</code></pre><p>代码执行流程如下:</p><p>从数据库中获取所有客户的流<br/>应用函数拜访每个客户对象并进行过滤<br/>只返回名为“Alice”的客户</p><p>当在Java中执行此代码时,Jinq将主动将代码转换为数据库能够了解的SQL查问。</p><pre><code class=“java”>PreparedStatement s = con.prepareStatement(“SELECT * ““FROM Customer C ““WHERE C.Name = ? “);s.setString(1, “Alice”);ResultSet rs = s.executeQuery();</code></pre><p>更少的谬误。更少的安全漏洞。更快的开发速度。</p><p>现有的数据库查问写在字符串外部。为了查看谬误,你必须启动数据库并运行查问。这会减慢开发速度并导致更多谬误。</p><p>Jinq查问是一般的Java代码,Java编译器将晚期捕捉谬误,放慢开发速度。因为查问被编写为Java代码,因而不可能呈现常见的SQL注入平安问题。</p><h2>立刻尝试</h2><p>Jinq是开源的。当初下载并依照入门指南学习更多对于其性能的信息。</p><h2>参考资料</h2><p>https://www.jinq.org/</p><blockquote>本文由博客一文多发平台 OpenWrite 公布!</blockquote></article>

March 5, 2024 · 1 min · jiezi

关于后端:自定义-OpenTelemetry-Collector-容器镜像

<article class=“article fmt article-content”><p></p><p>OpenTelemetry Collector 有两个官网发行版:Core 和 Contrib。</p><ul><li>Core 发行版是 Collector 的根底发行版,供 OTel 开发人员进行开发和测试。它蕴含一组根本的扩大、连接器、接收器、处理器和导出器。</li><li>Contrib 发行版供非 OTel 开发人员进行试验和学习。它还扩大了 Core 发行版,并蕴含由第三方(包含供应商和集体社区成员)创立的组件,这些组件对整个 OpenTelemetry 社区十分有用。在之前的文章 《应用 OpenTelemetry 和 Loki 实现高效的利用日志采集和剖析》 我用的就是这个发行版。</li></ul><p>不论 Core 还是 Contrib 都不应该成为你生产工作负载的一部分。仅仅应用 Core 自身太过简略,无奈满足组织的需要(只管它提供的组件都是必须的);尽管 Contrib 中提供的组件足够全面,然而并不是说每个组件都是你所须要的,太多冗余的组件显得过于臃肿,还增大的攻击面。</p><p>那如何抉择你所需的发行版呢?答案就是构建本人的发行版。能够应用官网提供的名为 OpenTelemetry Collector Builder (OCB) 的工具来自定义附件。</p><h3>装置 OCB</h3><p>ocb 是个简略的 CLI,反对 Window/Linux/macOS 以及 x86 和 arm64 平台。咱们能够从 release 页面 下载 ocb 的 binary。</p><pre><code class=“sh”>curl -o ocb -sL https://github.com/open-telemetry/opentelemetry-collector/releases/download/cmd%2Fbuilder%2Fv0.95.0/ocb_0.95.0_linux_amd64chmod +x ocb</code></pre><p>能够通过 <code>./ocb help</code> 查看应用办法。</p><p>还能够通过 <code>go install</code> 来装置。</p><pre><code>go install go.opentelemetry.io/collector/cmd/builder@latest</code></pre><p>要构建本人的发行版,须要应用上面的命令,通过 <code>–config</code> 指定配置文件,也就是上面要介绍的构建清单。</p><pre><code class=“sh”>./ocb –config=builder-config.yaml</code></pre><p>如果不提供,会应用 默认的清单文件。既然咱们是要构建本人的发行版,那接来看看如何配置构建清单。</p><h3>构建清单</h3><p>构建清单是对 OpenTelemetry Collector 的形容,通常蕴含如下几个局部:</p><ul><li><code> dist</code>:发行版的根本信息</li><li><code>receivers</code>:集成的 receiver 列表</li><li><code>exporters</code>:集成的 exporter 列表</li><li><code>extensions</code>:集成的 extension 列表</li><li><code>processors</code>:集成的 processor 列表</li><li><code>connectors</code>:集成的 receiver 列表</li></ul><p>从 GitHub 仓库中能够找到 core 发行版的构建清单,咱们能够基于该版本进行裁剪(去掉 replace 的局部)。</p><pre><code class=“yaml”>dist: module: go.opentelemetry.io/collector/cmd/otelcorecol name: otelcorecol description: Local OpenTelemetry Collector binary, testing only. version: 0.95.0-dev otelcol_version: 0.95.0 output_path: /tmp/distexporters: - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/loggingexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.95.0extensions: - gomod: go.opentelemetry.io/collector/extension/ballastextension v0.95.0 - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.95.0 - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.95.0processors: - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.95.0 - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.95.0connectors: - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.95.0</code></pre><p>当初为 结尾提到的文章 构建 OpenTelemetry Collector 发行版,在 <code>exporters</code> 中增加 <code>lokiexporter</code>。在 contrib 仓库 中能够找到更多的组件。</p><pre><code class=“sh”>dist: module: go.opentelemetry.io/collector/cmd/otelcorecol name: otelcorecol description: Local OpenTelemetry Collector binary, testing only. version: 0.95.0-dev otelcol_version: 0.95.0 output_path: /tmp/distreceivers: - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.95.0exporters: - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/loggingexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.95.0 - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.95.0 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/lokiexporter v0.95.0extensions: - gomod: go.opentelemetry.io/collector/extension/ballastextension v0.95.0 - gomod: go.opentelemetry.io/collector/extension/memorylimiterextension v0.95.0 - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.95.0processors: - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.95.0 - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.95.0 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.95.0connectors: - gomod: go.opentelemetry.io/collector/connector/forwardconnector v0.95.0</code></pre><p>这样就筹备好了构建清单,执行上面的命令,而后在 <code>dist.output_path</code> 指定的目录中能够到找构建好的二进制文件。</p><pre><code class=“shell”>./ocb –config=builder-config.yaml</code></pre><h3>构建镜像</h3><p>通过下面的办法来构建 collector 的二进制文件,进一步再构建容器镜像。</p><pre><code class=“Dockerfile”>FROM golang:1.21 as buildARG OTEL_VERSION=0.95.0WORKDIR /appCOPY . .RUN go install go.opentelemetry.io/collector/cmd/builder@v${OTEL_VERSION}RUN CGO_ENABLED=0 builder –config=builder-config.yamlFROM gcr.io/distroless/base-debian11COPY –from=build /tmp/dist/otelcorecol /# 4317 - default OTLP receiver# 55678 - opencensus (tracing) receiver# 55679 - zpagesEXPOSE 4317/tcp 55678/tcp 55679/tcpCMD ["–config", “/etc/otelcol-contrib/config.yaml”]ENTRYPOINT ["/otelcorecol"]</code></pre><p>我曾经构建好了镜像 <code>addozhang/opentelemetry-collector:0.95.0</code> ,在创立 CR <code>OpenTelemetryCollector</code> 的时候,能够将镜像批改为咱们定制的镜像。</p><blockquote>关注"云原生指北"公众号<br/><br/>(转载本站文章请注明作者和出处盛世浮生,请勿用于任何商业用途)</blockquote></article> ...

March 5, 2024 · 2 min · jiezi

关于后端:深入浅出Redis二Redis单线程模型与通信流程

<article class=“article fmt article-content”><h3>引言</h3><p>Redis是一款基于键值对的数据结构存储系统,它的特点是<strong>基于内存操作、单线程解决命令、IO多路复用模型解决网络申请、键值对存储与简略丰盛的数据结构</strong>等等</p><p>本篇文章次要围绕<strong>Redis中IO多路复用模型解决网络申请的特点</strong>来先从介绍IO模型,IO多路复用模型以及客户端与服务端的通信</p><h3>IO模型</h3><ul><li><p>IO申请(读)数据会切换至操作系统内核态来实现真正数据读取,而读取又分为两个阶段,别离为:</p><ol><li><strong>期待数据</strong>:调用后须要期待数据筹备好</li><li><strong>复制数据</strong>:当筹备好数据后,将数据从内核空间复制到用户空间</li></ol></li></ul><blockquote>常见IO模型</blockquote><ul><li><p>同步阻塞IO:收回IO申请(零碎调用)后,阻塞期待内核筹备数据,数据筹备好了再把数据从内核空间拷贝到用户空间</p><p></p><ul><li><strong>一个线程解决一个客户端,同时解决大量网络申请时须要的线程太多 ,且线程IO申请时阻塞</strong></li></ul></li></ul><p><!—-></p><ul><li><p>同步非阻塞IO:线程轮循发动IO申请,如果没筹备好数据返回告知数据未筹备好,这样就会下次再轮循拜访,如果数据筹备好了就可能将数据从内核空间复制到用户空间</p><p></p><ul><li><strong>一个线程解决一个客户端,同时解决大量网络申请时须要的线程太多,尽管线程IO申请时不阻塞,然而轮循发动IO申请会节约CPU(CPU空转)</strong></li></ul></li></ul><p><!—-></p><ul><li><p>IO多路复用:应用选择器(select)阻塞期待事件,当监听accept事件阐明要建设连贯(与对应客户端建设套接字连贯能力进行读写事件),一次监听可能携带多个事件须要解决</p><p></p><ul><li><strong>一个线程监听多个客户端,轮循select阻塞,监听到套接字触发读/写事件时再进行解决(循环解决可能有多个客户端同时触发读写事件)</strong></li></ul></li></ul><p>没看懂IO多路复用模型的同学能够持续往下看,下文会具体介绍IO多路复用模型的流程</p><h3>通信</h3><p>通信流程次要划分为:服务端要进行初始化,初始化后才开始循环处理事件,服务端在处理事件期间会保护客户端相干信息</p><h4>服务端初始化</h4><p>初始化</p><ol><li>初始化服务端默认配置</li><li>依据启动命令更改配置</li><li>初始化数据结构</li><li>依据AOF或RDB复原数据(依据长久化策略复原数据,后续长久化文章会具体介绍)</li><li>开始事件循环(处理事件)</li></ol><h4>处理事件</h4><p>处理事件能够看成解决客户端申请与保护治理服务端本身的资源</p><p>事件被分为文件事件和工夫工夫</p><p><strong>文件事件常是解决客户端申请,工夫事件常是定时、周期工作来查看/治理服务端资源</strong></p><h5>文件事件</h5><p><strong>Redis 应用IO多路复用模型 监听多个客户端的套接字,当感知到套接字上产生事件时,将事件放入队列中,由文件事件分派器顺次取出事件并交给对应事件处理器解决</strong></p><p></p><p>事件类型能够分为<strong>读事件AE_READABLE、写事件AE_WRITEABLE</strong>,读写是以服务器为核心(起始)的,比方客户端发动连贯申请、发送命令申请都是触发读事件,而客户端须要读响应时是触发写事件</p><p>事件处理器有<strong>连贯应答处理器(解决连贯的读事件),命令申请处理器(解决读事件),命令回复处理器(解决写事件),复制处理器(用于主从复制)</strong> 等等,本文次要应用连贯应答、命令申请、回复三种处理器</p><ul><li><p>流程</p><ol><li><strong>服务端初始化时,连贯应答处理器与服务端监听套接字的读事件关联</strong></li><li><strong>客户端申请连贯时,服务端套接字触发读事件,服务端监听到读事件并放入队列中,事件分派器取出后交给连贯应答处理器解决,并将客户端套接字的读事件与命令申请处理器关联</strong></li><li><strong>客户端发送命令申请时,客户端套接字触发读事件,服务端监听到读事件并放入队列,事件分派器交给命令申请处理器解决,执行命令,筹备回复,将客户端套接字的写事件与命令回复处理器关联</strong></li><li><strong>客户端筹备读回复时,客户端套接字触发写事件,服务端监听到写事件并放入队列,事件分派器交给命令回复处理器解决,返回响应,勾销命令回复处理器与客户端套接字写事件的关联</strong></li></ol></li></ul><p></p><h5>工夫事件</h5><p>工夫事件分为<strong>定时工夫事件和周期时间事件,定时为规定事件做一次,周期为以多少工夫为周期做一次</strong></p><p>工夫事件处理器<strong>应用链表治理定时、周期事件,定期遍历链表,判断工夫事件是否到期,到期则执行,执行完判断工夫事件如果为定时则删除,为周期则更改下个周期达到工夫</strong></p><p>工夫事件较少,基本上都是做一些定期检查,次要解决文件事件</p><p><strong>服务器优先解决文件事件再解决工夫事件</strong></p><h4>客户端信息</h4><p>服务端应用<strong>RedisClient对象来存储客户端相干信息,应用链表治理RedisClient</strong>(所有连贯的客户端)</p><ul><li><p>redis client 信息</p><ul><li><p>套接字描述符,判断客户端是否为伪客户端</p><ul><li>aof伪客户端:aof客户端执行aof文件,执行完敞开</li><li>lua脚本伪客户端:执行lua脚本,整个生命周期都存在</li></ul></li><li>客户端名字、客户端标记(主从,状态等)、是否身份验证</li><li><strong>输出缓冲区:保留序列化的命令申请</strong></li><li><strong>命令argv 与 参数个数 args :解析序列化命令申请 失去命令与参数个数</strong></li><li><strong>命令相干信息cmd : 依据argv 查问字典 失去命令相干的信息rediscommand</strong></li><li><strong>输入缓冲区:保留回复响应,如果短字符串应用固定缓冲区(字节数组),如果长字符串应用动静缓冲区(链表+字符串)</strong></li><li>工夫:记录连接时间等信息</li></ul></li></ul><h4>通信流程</h4><ul><li><p><strong>服务端解决申请流程</strong></p><ol><li><strong>用户发送命令到客户端,客户端序列化后发送给服务端</strong> (客户端与服务端建设连贯时,连贯应答处理器解决,让客户端套接字读事件关联到命令申请处理器)</li><li><p><strong>服务端读取命令申请</strong> (监听到读事件产生,最终由命令申请处理器解决)</p><ul><li><strong>服务端接管序列化申请,解析出命令和参数个数填充属性argv、args参数</strong></li><li><strong>通过命令argv与字典查问该命令相干信息 cmd指向该rediscommand</strong></li></ul></li><li><p><strong>服务端执行命令</strong> (执行完放到缓冲区,让客户端套接字写事件关联到命令回复处理器)</p><ul><li><strong>执行前查看参数个数、身份验证等操作</strong></li><li><strong>执行并将回复保留在输入缓冲区</strong></li><li><strong>执行后查看慢查问、写AOF缓冲等操作</strong></li></ul></li><li><strong>服务端回复响应给客户端,客户端反序列化展现给用户</strong>(客户端筹备读取触发写事件,命令回复处理器解决响应回去,勾销关联)</li></ol></li></ul><p>定时工作通常用来治理服务器资源:更新缓冲工夫、每秒执行命令数量、已应用内存峰值,解决sigterm信号敞开前RDB,治理客户端连贯、数据库资源,判断是否须要长久化等</p><h3>总结</h3><p>本文以Redis应用IO多路复用模型解决网络申请的为终点,介绍了IO模型,服务端初始化,服务端解决文件、工夫事件,客户端信息以及残缺的通信流程</p><p><strong>同步阻塞IO模型,在解决大量网络申请时须要消耗一比一的线程,且产生零碎调用读数据时线程会阻塞</strong></p><p><strong>同步非阻塞IO模型,尽管不阻塞但存在CPU空转,节约性能</strong></p><p><strong>IO多路复用模型应用select监听套接字上的读写事件,select会阻塞,当监听到客户端套接字触发读写事件时,遍历解决所有套接字的读写事件</strong></p><p><strong>服务端初始化时次要是依据配置文件以及启动命令进行资源、数据结构的初始化,同时会依据长久化策略寻找RDB、AOF文件进行数据恢复,初始化完才开始循环处理事件</strong></p><p><strong>事件能够分为文件事件和工夫事件,文件事件罕用来解决客户端申请,分为读、写事件,当客户端套接字触发读、写事件时,将事件放入队列,文件事件分派器将队列中的事件顺次交给对应的事件处理器;工夫事件常是定时、周期工作,用来查看/治理服务端本身资源等</strong></p><p><strong>服务端处理事件期间,会应用链表治理保护客户端相干信息:输出缓冲区(序列化的命令申请)、命令与命令参数个数、命令相干信息(通过这些可能执行命令)、输入缓冲区(保留回复响应)</strong></p><p><strong>整体流程:</strong></p><ol><li><strong>服务端依据配置文件、启动命令初始化数据结构,将连贯应答处理器与服务端监听套接字的读事件关联</strong></li><li><strong>客户端发动申请建设连贯时,服务端监听套接字读事件触发,连贯应答处理器将客户端套接字读事件与命令申请处理器关联</strong></li><li><p><strong>当客户端发送到服务端时,触发读事件,由命令申请处理器解决</strong></p><ul><li><strong>解析输出缓冲区的序列化申请,解析完保留欠缺客户端信息(命令相干信息)</strong></li><li><strong>执行前查看参数个数、身份验证等</strong></li><li><strong>依据客户端保留命令相干信息执行函数</strong></li><li><strong>执行后还可能须要查看一些操作(如:查看慢查问、是否要写AOF缓冲区等),执行后将后果保留在输入缓冲区,让客户端套接字写事件关联命令回复处理器</strong></li></ul></li><li><strong>当客户端筹备读时触发写事件,命令回复处理器将输入缓冲区响应返回</strong></li></ol><h3>最初(一键三连求求拉~)</h3><p>本篇文章笔记以及案例被支出 gitee-StudyJava、 github-StudyJava 感兴趣的同学能够stat下继续关注喔~</p><p>有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下~</p><p>关注菜菜,分享更多干货,公众号:菜菜的后端私房菜</p><blockquote>本文由博客一文多发平台 OpenWrite 公布!</blockquote></article>

March 5, 2024 · 1 min · jiezi

关于后端:大厂报价查询系统性能优化之道

0 前言机票查问零碎,日均亿级流量,要求高吞吐,低提早架构设计。晋升缓存的效率以及实时计算模块长尾提早,成为制约机票查问零碎性能要害。本文介绍机票查问零碎在缓存和实时计算两个畛域的架构晋升。 1 机票搜寻服务概述1.1 机票搜寻的业务特点机票搜寻业务:输出目的地,而后点击搜寻,后盾就开始卷了。根本1~2s将最优后果反给用户。这个业务存在以下业务特点。 1.1.1 高流量、低延时、高成功率超高流量,同时,对搜寻后果要求也很高——成功率要高,不能查问失败或强说胜利,心愿能反给用户最优最新数据。 1.1.2 多引擎聚合,SLA不一机票搜寻数据起源哪?很大一部分起源本人的机票运价引擎。为补充产品丰富性,还引入国内一些GDS、SLA,如联航。将内部引擎和本人引擎后果聚合后发给用户。 1.1.3 计算密集&IO密集大家可能意识到,我说到咱们本人的引擎就是基于一些运价的数据、仓位的数据,还有其余一些航班的信息,咱们会计算、比对、聚合,这是一个十分技术密计算密集型的这么一个服务。同时呢,内部的GDS提供的查问接口或者查问引擎,对咱们来说又是一个IO密集型的子系统。咱们的搜寻服务要将这两种不同的引擎后果很好地聚合起来。 1.1.4 不同业务场景的搜寻后果不同要求作为OTA巨头,还反对不同利用场景。如同样北京飞上海,因为搜寻条件或搜寻渠道不一,返回后果有所不同。如客户是学生,可能搜到学生特价票,其余用户就看不到。 2 公司基建为应答如此业务,有哪些利器? 2.1 三个独立IDC相互做灾备,实现其中一个IDC齐全宕机,业务也不受影响。 2.2 DataCenter技术栈SpringCloud+K8s+云服务(海内),感激Netflix开源撑持国内互联网极速倒退。 2.3 基于开源的DevOps咱们基于开源做了整套的DevOps工具和框架。 2.4 多种存储计划公司外部有比较完善可用度比拟高的存储计划,包含MySQL,Redis,MangoDB…… 2.5 网络可靠性重视网络可靠性,做了很多DR开发,SRE实际,宽泛推动熔断,限流等,以保障用户失去高质量服务。 3 机票搜寻服务架构3.1 架构图 IDC有三个,先引入GateWay分流前端服务,前端服务通过服务治理,和后端聚合服务交互。聚合服务再调用很多引擎服务。 聚合服务后果,通过Kafka推到AI数据平台,做大数据分析、流量回放等数据操作。云上部署数据的过滤服务,使传回数据缩小90%。 4 缓存架构4.1 缓存的挑战和策略4.1.1 为啥大量应用缓存应答流量顶峰?提高效率、速度的首选技术手段。 虽应用很多开源技术,但还有瓶颈。如数据库是分片、高可用的MySQL,但和一些云存储、云数据库比,其带宽、存储量、可用性有差距,通常需用缓存爱护咱们的数据库,不然频繁读取会使数据库很快超载。 很多内部依赖,提供给咱们的带宽,QPS无限。而公司整体业务量是快速增长的,而内部的业务搭档给咱们的带宽,要么已达技术瓶颈,要么开始收高费用。此时,应用缓存就可爱护内部的一些合作伙伴,不至于击穿他们的零碎,也可帮咱们降本。 4.1.2 本地缓存 VS 分布式缓存整个架构的演进过程,一开始本地缓存较多,起初局部用到分布式缓存。 本地缓存的次要问题: 启动时,有个冷启动过程,对疾速部署不利与分布式缓存相比,本地缓存命中率太低对海量的数据而言,单机提供命中率非常低,5%甚至更低。对此,现已全面切向Redis分布式缓存。本着对战failure的理念,不得不思考失败场景。万一集群挂掉或一部分分片挂掉,这时须要通过限流客户端、熔断等,避免雪崩效应。 4.1.3 TTL命中率新鲜度动静更新TTL生命周期跟业务强相干。买机票常常遇到:刚在报价列表页看到一个高价机票,点进报价详情页就没了,why?航空公司高价舱位票,一次可能只放几张,若在热门航线,可能同时几百人在查,它们都可能看到这几张票,它就会呈现在缓存里。若已有10人订了票,其他人看到缓存再点进去,运价就已生效。对此,就要求衡量,不能片面追求高命中率,还得兼顾数据新鲜度。为保障新鲜度、数据准确性,还有大量定时工作去做更新和清理。 4.2 缓存架构演进4.2.1 多级缓存架构图的三处缓存: 引擎级缓存L1分布式聚合缓存,基本上就是用户看到的最终查问后果L2二级缓存,分布式的子引擎后果若聚合服务需多个返回后果,很大水平都是先读一级缓存,一级缓存没有命中的话,再从二级缓存外面去读两头后果,这样能够疾速聚合出一个大家所须要的后果返回。 4.2.2 引擎缓存引擎缓存: 查问后果缓存两头产品缓存根底数据缓存应用一个多级缓存模式。如下图,最顶部是指引前的后果缓存,贮存在Redis,引擎外部依据产品、供应商,有多个渠道的两头后果,所以对子引擎来说会有个两头缓存。 这些两头后果计算,须要数据,这数据就来自最根底的一级缓存。 4.2.3 基于Redis的一级缓存Pros: 读写性能高程度扩大Cons: 固定TTL命中率和新鲜度的均衡后果: 命中率<20%高新鲜度(TTL<5m,动静刷新读写提早<3ms 一级缓存应用Redis,是思考其读写性能好,疾速,程度扩大性能,能进步存储量及带宽。但以后设计局限性: 为简略,应用固定TTL,这是为保障返回后果的绝对陈腐为命中率和新鲜度,还在一直进步目前解决方案还不能完满解决这俩问题。 剖析下返回后果,一级缓存命中率小于20%,某些场景更低,就是为保障更高准确度和新鲜度。高优先度,一级缓存的TTL必定低于5min,有些场景可能只有几十s;反对动静刷新,整体提早小于3ms。整个运行过程可用性较好。 4.2.4 基于Redis的二级缓存(架构降级)Pros: 读写性能进一步晋升服务可靠性晋升老本消减Cons: 减少复杂性代替二级索引后果: 老本升高90%读写性能晋升30% 4.2.5 基于MongoDB的二级缓存二级缓存一开始用MongoDB: ...

March 4, 2024 · 1 min · jiezi

关于后端:Git-安全远程访问SSH-密钥对生成添加和连接步骤解析

应用 SSH 密钥对的 Git 平安近程拜访:生成、增加和连贯SSH(Secure Shell)是一种用于平安近程拜访的协定,它提供了加密通信和身份验证机制。在应用 SSH 连贯到近程 Git 存储库时,您能够应用 SSH 密钥对来确保安全性。以下是对于如何生成和应用 SSH 密钥对的具体步骤: 生成 SSH 密钥对 关上终端或命令行工具。在命令行中运行以下命令来生成 SSH 密钥对: ssh-keygen -t rsa -b 4096 -C "your_email@example.com"这将创立一个 RSA 密钥对,其中 -t 用于指定密钥类型,-b 用于指定密钥位数(通常为 4096 位,更平安),-C 用于增加正文,通常是您的电子邮件地址。 零碎会要求您抉择密钥对的保留地位。按 Enter 应用默认地位(通常在 ~/.ssh/id_rsa)或指定其余地位。您还能够抉择为 SSH 密钥对设置明码,进步安全性。这意味着在每次应用密钥对时,您都须要输出明码。如果抉择设置明码,零碎将要求您输出明码并进行确认。SSH 密钥对已生成,公钥保留在 ~/.ssh/id_rsa.pub 中,私钥保留在 ~/.ssh/id_rsa 中。增加 SSH 密钥到 SSH-Agent SSH-Agent 是一个密钥管理工具,用于治理 SSH 密钥并在须要时提供它们。 在终端中运行以下命令以将 SSH 密钥增加到 SSH-Agent: ssh-add ~/.ssh/id_rsa请将 ~/.ssh/id_rsa 替换为您生成密钥时抉择的门路。 如果您设置了明码,零碎将提醒您输出明码以解锁密钥。一旦实现,密钥将增加到 SSH-Agent 中。将公钥增加到 Git 存储库 关上 ~/.ssh/id_rsa.pub 文件,查看公钥内容。您能够应用文本编辑器来关上该文件。复制公钥内容。登录到您的 Git 存储库托管服务(例如 GitHub、GitLab 或 Bitbucket)。转到您的账户设置或配置文件设置中,找到 SSH 密钥或公共密钥局部。增加您的公钥。这通常波及将公钥粘贴到提供的字段中并保留更改。应用 SSH 连贯到近程存储库 ...

March 4, 2024 · 1 min · jiezi

关于后端:程序员必备的linux常用的26条命令

04 穿梭功耗墙,咱们该从哪些方面晋升“性能”?上一讲,在讲 CPU 的性能时,咱们提到了这样一个公式: 程序的 CPU 执行工夫 = 指令数×CPI×Clock Cycle Time 这么来看,如果要晋升计算机的性能,咱们能够从指令数、CPI 以及 CPU 主频这三个中央动手。要搞定指令数或者 CPI,乍一看都不太容易。于是,研发 CPU 的硬件工程师们,从 80 年代开始,就挑上了 CPU 这个“软柿子”。在 CPU 上多放一点晶体管,一直晋升 CPU 的时钟频率,这样就能让 CPU 变得更快,程序的执行工夫就会缩短。 于是,从 1978 年 Intel 公布的 8086 CPU 开始,计算机的主频从 5MHz 开始,一直晋升。1980 年代中期的 80386 可能跑到 40MHz,1989 年的 486 可能跑到 100MHz,直到 2000 年的奔流 4 处理器,主频曾经达到了 1.4GHz。而消费者也在这 20 年里养成了“看主频”买电脑的习惯。过后曾经根本垄断了桌面 CPU 市场的 Intel 更是夸下了海口,示意奔流 4 所应用的 CPU 构造能够做到 10GHz,颇有一点“鼎力出奇观”的意思。 功耗:CPU 的“人体极限”然而,计算机科学界从来不置信“鼎力出奇观”。奔流 4 的 CPU 主频素来没有达到过 10GHz,最终它的主频下限定格在 3.8GHz。这还不是最糟的,更蹩脚的事件是,大家发现,奔流 4 的主频尽管高,然而它的理论性能却配不上同样的主频。想要用在笔记本上的奔流 4 2.4GHz 处理器,其性能只和基于奔流 3 架构的奔流 M 1.6GHz 处理器差不多。 ...

March 4, 2024 · 2 min · jiezi

关于后端:听-GPT-讲-clientgo-源代码-18

分享更多精彩内容,欢送关注! File: client-go/applyconfigurations/core/v1/secretenvsource.go在client-go我的项目中,secretenvsource.go文件定义了用于创立和利用SecretEnvSource对象的相干配置。SecretEnvSource构造体用于示意从Secret中获取的环境变量,其中的字段定义了Secret的名称和可选的前缀、键值对等信息。 SecretEnvSourceApplyConfiguration构造体是一个蕴含了SecretEnvSource的可选配置项的构造体,用于示意对SecretEnvSource对象的批改或扩大。它定义了一些Setter办法,以便用户能够对SecretEnvSource对象的字段进行设置。例如,WithName办法用于设置Secret的名称,WithOptional办法用于将SecretEnvSource设置为可选项。 SecretEnvSource是一个对Secret中的环境变量进行形容的构造体,它蕴含了Secret的名称和可选的配置信息。通过调用WithName函数,用户能够指定Secret的名称;通过调用WithOptional函数,用户能够将SecretEnvSource设置为可选项。 总而言之,secretenvsource.go文件中的构造体和函数定义了用于创立和批改SecretEnvSource对象的配置信息,并提供相应的办法进行设置和操作。 File: client-go/tools/cache/fifo.go在K8s组织下的client-go我的项目中,client-go/tools/cache/fifo.go文件的作用是实现一个简略的先进先出(FIFO)队列。 ErrFIFOClosed是一个示意FIFO队列已敞开的谬误变量。PopProcessFunc是FIFO队列的处理函数类型。ErrRequeue是一个示意须要从新排队的谬误变量。接下来介绍各个构造体的作用: Queue构造体是FIFO队列的根本实现,提供了根本的队列操作方法。FIFO构造体是Queue构造体的扩大,它实现了一个具备数据处理性能的FIFO队列。能够应用PopProcessFunc将处理函数与FIFO队列关联起来。以下是各个函数的作用: Error办法用于返回ErrFIFOClosed谬误。Pop办法用于从FIFO队列中获取下一个元素,并将其从队列中移除。Close办法用于敞开FIFO队列。HasSynced办法用于查看FIFO队列是否已同步实现。hasSynced_locked办法用于判断FIFO队列是否处于同步状态。Add办法用于将一个元素增加到FIFO队列中。AddIfNotPresent办法用于判断元素是否已存在于FIFO队列中,如果不存在则将其增加。addIfNotPresent办法理论执行元素增加操作。Update办法用于更新FIFO队列中已存在的元素。Delete办法用于从FIFO队列中删除指定的元素。List办法用于获取FIFO队列中的所有元素。ListKeys办法用于获取FIFO队列中所有元素的key。Get办法用于依据指定的key从FIFO队列中获取元素。GetByKey办法用于依据指定的key从FIFO队列中获取元素,并返回元素的值和是否存在的标识。IsClosed办法用于判断FIFO队列是否已敞开。Replace办法用于替换FIFO队列中已存在的元素。Resync办法用于从新同步FIFO队列的状态。NewFIFO办法用于创立一个新的FIFO队列,并返回该队列的指针。File: client-go/applyconfigurations/apps/v1beta2/statefulset.go在client-go我的项目中,client-go/applyconfigurations/apps/v1beta2/statefulset.go文件的作用是定义了StatefulSet的apply配置。具体来说,该文件中蕴含了StatefulSetApplyConfiguration构造体和一些相干的函数。上面逐个介绍这些构造体和函数的作用: StatefulSetApplyConfiguration构造体:该构造体定义了StatefulSet对象的apply配置。它蕴含了StatefulSet的所有字段,能够通过配置这些字段来指定StatefulSet对象的冀望状态。StatefulSet:该函数用于创立一个新的StatefulSetApplyConfiguration对象。它承受一个可变参数func(*StatefulSetApplyConfiguration),并通过调用该参数函数来设置StatefulSetApplyConfiguration对象的字段值。ExtractStatefulSet:该函数用于从一个已有的StatefulSet对象中提取出其apply配置,返回一个*StatefulSetApplyConfiguration对象。ExtractStatefulSetStatus:该函数用于从一个已有的StatefulSet对象中提取出其状态字段的apply配置,返回一个*StatefulSetStatusApplyConfiguration对象。extractStatefulSet:该函数用于从一个已有的StatefulSet对象中提取出其元数据字段的apply配置,返回一个*ObjectMetaApplyConfiguration对象。WithKind、WithAPIVersion、WithName、WithGenerateName、WithNamespace、WithUID、WithResourceVersion、WithGeneration、WithCreationTimestamp、 WithDeletionTimestamp、WithDeletionGracePeriodSeconds:这些函数用于设置StatefulSet对象的元数据字段的apply配置。WithLabels、WithAnnotations、WithOwnerReferences、WithFinalizers:这些函数用于设置StatefulSet对象的元数据字段中的标签、注解、所有者援用和终结器的apply配置。ensureObjectMetaApplyConfigurationExists:该函数用于确保StatefulSet对象的元数据字段的apply配置不为nil。WithSpec:该函数用于设置StatefulSet对象的spec字段的apply配置。WithStatus:该函数用于设置StatefulSet对象的status字段的apply配置。总的来说,client-go/applyconfigurations/apps/v1beta2/statefulset.go文件中定义了StatefulSet的apply配置构造体和函数,通过这些构造体和函数,能够不便地创立、配置和提取StatefulSet对象的apply配置。 File: client-go/applyconfigurations/discovery/v1beta1/endpointconditions.go在client-go我的项目中,endpointconditions.go文件是用于定义和利用Endpoint的条件的。它蕴含了EndpointConditionsApplyConfiguration构造体、EndpointConditions构造体以及几个相干的函数,上面逐个介绍: EndpointConditionsApplyConfiguration构造体:它示意EndpointConditions的利用配置。EndpointConditions用于指定Endpoint对象的各个条件,例如Ready、Serving和Terminating。EndpointConditionsApplyConfiguration是对EndpointConditions的配置进行更改和更新的构造体。EndpointConditions构造体:它用于形容Endpoint的条件状态。Endpoint示意能够让客户端连贯的网络起点,EndpointConditions用于批示Endpoint的准备就绪状态、服务状态和终止状态的条件。WithReady函数:它是EndpointConditionsApplyConfiguration构造体中的办法,用于设置EndpointConditions对象的Ready状态。Ready状态示意Endpoint是否已准备就绪,能够承受客户端的连贯。WithServing函数:它是EndpointConditionsApplyConfiguration构造体中的办法,用于设置EndpointConditions对象的Serving状态。Serving状态示意Endpoint是否正在提供服务,即是否能够解决客户端的申请。WithTerminating函数:它是EndpointConditionsApplyConfiguration构造体中的办法,用于设置EndpointConditions对象的Terminating状态。Terminating状态示意Endpoint正在终止,即行将进行服务。这些函数提供了一种不便的办法来配置并更新EndpointConditions对象的状态。通过应用这些函数,能够创立或批改EndpointConditions对象的各个条件,以反映Endpoint的状态。 File: client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go在Kubernetes (K8s) 组织下的 client-go 我的项目中,clustertrustbundle.go 文件的作用是定义了与集群信赖捆绑相干的 API 对象和配置。 具体来说,该文件定义了几个要害的构造体和办法: ClusterTrustBundleApplyConfiguration 构造体是一个 ApplyConfiguration 对象,它蕴含了对集群信赖捆绑进行利用配置所需的参数。ClusterTrustBundle 构造体是一个 ClusterTrustBundleApplyConfiguration 对象,它示意了一个集群信赖捆绑资源。该构造体继承了 ClusterTrustBundleApplyConfiguration,并增加了理论的数据字段。ExtractClusterTrustBundle 构造体是一个 Extractor 对象,用于从原始对象中提取 ClusterTrustBundle 对象。ExtractClusterTrustBundleStatus 构造体是一个 Extractor 对象,用于从原始对象中提取 ClusterTrustBundle 的状态信息。extractClusterTrustBundle 办法是一个 Extractor 函数,用于从原始对象中提取 ClusterTrustBundle 对象。WithKind、WithAPIVersion、WithName、WithGenerateName、WithNamespace、WithUID、WithResourceVersion、WithGeneration、WithCreationTimestamp、WithDeletionTimestamp、WithDeletionGracePeriodSeconds、WithLabels、WithAnnotations、WithOwnerReferences 和 WithFinalizers 都是用于设置 ClusterTrustBundle 对象的不同属性的办法。ensureObjectMetaApplyConfigurationExists 办法用于确保对象的元数据利用配置存在。WithSpec 办法用于设置 ClusterTrustBundle 对象的 spec 字段,其中蕴含了捆绑的证书和其余相干配置。总体来说,clustertrustbundle.go 文件定义了操作集群信赖捆绑资源的构造体、办法和配置对象,使得开发人员能够在 client-go 中针对集群信赖捆绑资源进行操作和配置。 File: client-go/listers/batch/v1/job_expansion.goUnderstanding the Purpose of job_expansion.go in the client-go ProjectThe job_expansion.go file in the client-go/listers/batch/v1 package of the Kubernetes client-go project is responsible for providing expanded functionality and additional methods for working with Job resources in Kubernetes. ...

March 4, 2024 · 3 min · jiezi

关于后端:活动报名|AutoMQ-x-阿里云云原生创新论坛20240309见证新一代云原生-Kafka-重磅发布

新一年, AutoMQ 首场线下流动重磅来袭!2024年3月9日,由 AutoMQ 与阿里云联结举办的云原生翻新论坛将于杭州与大家见面,单方联结重磅公布新一代云原生 Kafka ——AutoMQ On-Prem 版本 !现场将会分享如何通过云原生和存算拆散架构实现 Kafka 产品的10倍老本优化,并放弃秒级分区无损迁徙。另外,流动现场还有来自得物的技术专家分享 AutoMQ 在生产场景中的利用实际,以及阿里云的资深专家为大家分析多 AZ 块存储的原理。 流动议程 本次流动中,咱们为参加互动的搭档筹备了精美周边礼品。快来扫码或者点击流动行链接报名,与 AutoMQ & 阿里云一起见证“新一代云原生 Kafka ”重磅公布!现场揭秘更多技术细节! 点击链接查看往期云原生翻新论坛回顾: 精彩回顾 | Apache Kafka × RocketMQ 云原生翻新论坛杭州站 [流动回顾 | AutoMQ 云原生翻新论坛精彩回放 ](http://mp.weixin.qq.com/s?__biz=MzkxNzY0ODE2Ng==&mid=22474840...) [ ](http://mp.weixin.qq.com/s?__biz=MzkxNzY0ODE2Ng==&mid=22474840...) END 对于咱们AutoMQ 是一家业余的音讯队列和流存储软件服务供应商。AutoMQ 开源的 AutoMQ Kafka 和 AutoMQ RocketMQ 基于云对 Apache Kafka、Apache RocketMQ 音讯引擎进行从新设计与实现,在充分利用云上的竞价实例、对象存储等服务的根底上,兑现了云设施的规模化红利,带来了下一代更稳固、高效的音讯引擎。此外,AutoMQ 推出的 RocketMQ Copilot 专家系统也从新定义了 RocketMQ 音讯运维的新范式,赋能音讯运维人员更好的治理音讯集群。   GitHub 地址:https://github.com/AutoMQ/automq-for-kafka  官网:https://www.automq.com  B站:AutoMQ官网账号  视频号:AutoMQ  扫二维码退出咱们的社区群 关注咱们,一起学习更多云原生干货

March 4, 2024 · 1 min · jiezi

关于后端:混沌工程是谁背着我偷偷写-Bug-

前言GreptimeDB 反对以单机和分布式的模式进行部署,但紧随而来一个尖利的问题:咱们对投入生产的这套简单零碎有多少信念? 在 0.3 到 0.4 的迭代过程中,咱们引入了混沌工程(Chaos engineering)来进步零碎的健壮性。 混沌工程是怎么施行的咱们抉择了 Chaos Mesh 作为故障注入工具。咱们在 Pod 中运行一个测试程序(Testcase),该程序通过定义 CR(Custom Resource)为 DB 集群中特定的 Pod 注入故障;并在转移故障后,对 DB 集群的可用性和数据完整性进行验证。上面是一个示例,向 greptimedb-cluster 命名空间中名为 greptimedb-datanode-1 的 Pod 注入一个 Pod Kill 的故障。 apiVersion: chaos-mesh.org/v1alpha1kind: PodChaosmetadata: namespace: greptimedb-clusterspec: action: pod-kill mode: one selector: filedSelectors: 'metadata.name': 'greptimedb-datanode-1'为了便于调试测试程序,测试程序在开发环境中,能够间接运行在主机上,并通过 Kubectl 的端口转发拜访 K8s 中的 DB 服务。 一些摸索和教训1. 从最小场景开始测试笼罩不高时,可能会有一些“负负得正”的状况,让整套零碎看起来“失常”运行(实际上即便覆盖率较高,也仍然可能存在这些问题)。所以咱们能够从最小场景开始测试,这个阶段你须要十分清晰地晓得零碎的预期行为,并通过查看系统日志,判断零碎的行为是否真的合乎预期,以便发现问题后及时补相应的集成测试。 例如,咱们须要验证零碎是否能容忍 Datanode 节点被 Kill,并触发 Region Failover 流程(行将 Region 迁徙到其余可用节点)。咱们能够通过构建一个最小场景(大量表,大量数据)来进行验证,通常当故障被注入到故障真正产生会有肯定的工夫距离,此时咱们须要一些办法去判断零碎是否实在产生故障了。 通常有几种做法:通过调用 Kube API 察看 ReplicatSet 的 Pod 正本数量少于预期;亦或是通过对指标节点进行读写来感知——在观测到故障前不间断的发动一些(大量的)将会路由到指标节点的读写操作,当客户端会返回故障时,即可视为指标节点不可用。随后期待集群复原(例如调用 Kube API 期待 ReplicatSet 的 Pod 正本数量回到预期),咱们就能够开始验证服务可用性和数据的完整性。 ...

March 4, 2024 · 1 min · jiezi

关于后端:这波操作看麻了十亿行数据从71s到17s的优化之路

你好呀,我是歪歪。 春节期间关注到了一个对于 Java 方面的较量,很有意思。因为是开源的,我把我的项目拉下来试图学(白)习(嫖)他人的做题思路,在这期间一度让我产生了一个自我狐疑: 他们写的 Java 和我会的 Java 是同一个 Java 吗?不能让我一个人狐疑,所以这篇文章我打算带你盘一下这个较量,并且试图让你也产生狐疑。 赛题在 2024 年 1 月 1 日,一个叫做 Gunnar Morling 的帅哥,发了这样一篇文章: https://www.morling.dev/blog/one-billion-row-challenge/ 文章的题目叫做《The One Billion Row Challenge》,十亿行挑战,简称就是 1BRC,挑战的工夫是一月份整个月。 赛题的内容非常简单,你只须要看懂这个文件就行了: 文件的每一行记录的是一个气象站的温度值。气象站和温度分号分隔,温度值只会保留一位小数。 参赛者只须要解析这个文件,而后并计算出每个气象站的最小、最大和平均温度。依照字典序的格局输入就行了: 出题人还配了一个简图: 需要十分明确、简略,对不对? 为了让你彻底明确,我再给你举一个具体的例子。 假如文件中的内容是这样的: chengdu;12.0guangzhou;7.2;chengdu;6.3beijing;-3.6;chengdu;23.0shanghai;9.8;chengdu;24.3beijing;17.8;那么 chengdu (成都)的最低气温是 6.3,最高气温是 24.3,平均气温是(12.0+6.3+23.0+24.3)/4=16.4,就是这么朴实无华的计算形式。 最终后果输入的时候,再留神一下字典序就行。 这有啥好挑战的呢? 难点在于出题人给出的这个文件有 10 亿行数据。 在我的垃圾电脑上,光是跑出题人提供的数据生成的脚本,就跑了 20 分钟: 跑进去之后文件大小都有靠近 13G,记事本打都打不开: 所以挑战点就在于“十亿行”数据。 具体的一些规定形容和细节补充,都在 github 上放好了: https://github.com/gunnarmorling/1brc针对这个挑战,出题人还提供了一个基线版本: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_baseline.java首先封装了一个 MeasurementAggregator 对象,外面放的就是要记录的最小温度、最大温度、总温度和总数。 整个外围代码就二三十行,应用了流式编程: 首先是一行行的读取文本,接着每一行都依照分号进行拆分,取出对应的气象站和温度值。 而后依照气象站维度进行 groupingBy 聚合,并且计算最大值、最小值和平均值。 ...

March 4, 2024 · 4 min · jiezi

关于后端:maven-包管理平台08nexus-自己搭建-maven-仓库

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 NexusNexus 是组织、存储和散发软件组件的最佳形式。 下载下载装置办法: 蕴含Jetty的捆绑包,只需 JRE。我抉择了这种形式 nexus-2.13.0-01-bundle.tar.gz;War,能够部署在Web上。装置将文件解压到所需地位。蕴含两个文件夹: nexus-2.13.0-01 蕴含Nexus运行所需的内容。sonatype-work 蕴含配置、仓库、日志文件。启动进入 bin 文件夹,在 ~/nexus-2.13.0-01/bin 中运行 nexus,您可能会失去: houbinbindeMacBook-Pro:~ houbinbin$ /Users/houbinbin/IT/learn/nexus/nexus-2.13.0-01-bundle/nexus-2.13.0-01/bin/nexus ; exit;Usage: /Users/houbinbin/IT/learn/nexus/nexus-2.13.0-01-bundle/nexus-2.13.0-01/bin/nexus { console | start | stop | restart | status | dump }logoutSaving session......copying shared history......saving history...truncating history files......completed.因而,只需运行以下命令即可启动 Nexus 服务器。 ...

March 4, 2024 · 2 min · jiezi

关于后端:maven-包管理平台07plugins-常见插件介绍

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 maven 插件Maven 在其外围是一个插件执行框架;所有工作都由插件实现。 寻找要执行的特定指标吗?此页面列出了外围插件和其余插件。 有构建和报告插件: 构建(Build) 插件将在构建过程中执行,它们应该在 POM 中的 <build/> 元素中进行配置。报告(Reporting) 插件将在站点生成期间执行,它们应该在 POM 中的 <reporting/> 元素中进行配置。因为报告插件的后果是生成站点的一部分,所以报告插件应该同时进行国际化和本地化。您能够浏览更多对于插件本地化的信息以及您能够如何帮忙的内容。Maven 插件外围插件这些插件对应于默认的外围阶段(即 clean,compile 等)。 它们也可能有多个指标。 [compiler]()编译 Java 源代码。 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler-plugin.version}</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration></plugin>[surefire]()在隔离的类加载器中运行 JUnit 单元测试。 ...

March 4, 2024 · 3 min · jiezi

关于后端:国产数据库概述

这是ren_dong的第33篇原创1、什么是数据库?1.1、基本概念定义:数据库是依照肯定的数据结构组织、存储和治理数据的仓库。可视为电子化的文件柜,用户能够对文件中的数据进行新增、查问、更新、删除等操作。作用:业务数据存储和业务逻辑运算。数据库处于IT产业链中游,同时也造成了较为欠缺的数据库产业链 理论应用中,数据库通常与服务端搭配,通过服务端组件对数据库进行增删改查 1.2、数据库演进数据库的倒退法则遵循摩尔定律,从单机数据库、集群数据库、到现在云散布数据库、AINative数据库在数据库产品的演进中,其基于的数据模型也在发生变化。依据数据模型的不同,数据库能够分为关系型数据库(RDB)和非关系型数据库(NoSQL)。 关系型数据库的底层数据模型是关系模型。非关系型数据库是一个大类,其又能够分为不同品种的数据库。比方: 面向高性能并发读写的keyvalue数据库面向海量数据拜访的面向文档数据库面向可扩展性的分布式数据库常见的关系型数据库有Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL等。常见的非关系型数据库有 NoSql、Cloudant,Hbase等 2、国外数据库 寰球IT巨头在数据库方面都有所布局,从晚期的Oracle、IBM到前期的SAP等IT巨头 依据Gartner剖析型数据库魔力象限报告,Oracle、Microsoft处于领导者位置Oracle、MySQL在寰球数据库排名中始终霸榜,雄踞前三,排名走势非常稳固在数据库产品的竞争中,Oracle、MySQL劣势显著,一直吸引客户流入 3、国产数据库国产数据库研制的启动工夫晚、基础薄弱上世纪80年代末,90年代初,Oracle、IBM公司进军中国市场。20世纪末,中国数据库行业的格局未然成型: 金融行业中以 IBM 的DB2、Informix 的为主,电信行业中则被 Oracle 一统江湖我国数据库市场规模近 140 亿元,关系型数据库为支流。 Oracle、IBM、微软占据国内数据库市场,但国产品牌成长迅速,国产数据库市场份额一直晋升 3.1、数据库厂商国产数据库能够分为传统数据库、云数据库、开源数据库三类:依据源代码起源不同,国产数据库技术流派能够分为四大类:Oracle系,MySQL系,Informix系,PostgreSQL系 传统数据库特点为紧耦合,利用迁徙老本极高,大多数国产数据库厂商为了升高客户的迁徙老本,次要以开发Oracle兼容性作为次要方向国内次要有4大传统数据库厂商,即武汉达梦、南大通用、人大金仓、神州通用,前面会公布文章进行独自介绍End码字不易,欢送关注、点赞,感激反对! 本文由mdnice多平台公布

March 4, 2024 · 1 min · jiezi

关于后端:她来了为期三个月

副标题:【我和 TiDB 社区的故事】我与 TiDB 专栏的故事 两年前两年前,2022 年初,TiDB 社区专栏上线,将原 AskTUG 论坛的“技术文章”对立迁徙至专栏板块,TiDB 社区专栏板块旨在让技术人员成为更好的读者、作家。 截止至 2022.02.07,有 137 位社区技术布道师奉献了497 篇技术文章。1 涵盖了用户案例、最佳实际、技术教训分享、故障剖析案例等几大主题。 同年 3 月 14 日,TiDB 社区专栏第一届征文大赛,正式启动。 正值 TiDB 6.0 发版,整个大赛过程各位布道师输入了诸多 TiDB 6.0 相干文章。 首届征文大赛截至 5 月 31 日,流动共有 45 位小伙伴参加,有 103 篇优质文章输入。2 通过对优质文章的精心整顿和优化改良,最终公布了《TiDB 6.x in Action》电子书。3 ... 于我集体而言,那时刚刚考完 PCTP v5 认证,对 TiDB 也有了较为初步、概括性的理解。 于是抽出大量业余时间,全程参加了整个流动,凌晨写稿、改稿、校稿亦是粗茶淡饭。 在此次流动中,共入围 5 篇文章,其中 1 篇取得三等奖,1 篇获得最佳人气奖。 本次赛事共播种了 3 个奖牌,社区徽章,及 TiDB 周边若干。 同时,有幸与此,结识了很多技术大咖,在文章审校、电子书编辑过程中,也对 TiDB 有了更多的了解。 与 TiDB 社区的诸位“亲戚”的相逢,让我get到了开源社区能够这样丰富多彩。 ...

March 3, 2024 · 2 min · jiezi

关于后端:Ai必学系列一如何极速创建GPTs

什么是GPTsGPTs是OpenAI推出的一种自定义版本的ChatGPT。它容许用户依据本人的特定需要和目标,创立和定制专属的ChatGPT版本。GPTs联合了指令、额定常识和任意技能组合,提供了一种更智能、更个性化的体验。用户能够通过OpenAI的平台创立本人的GPTs,并与其余用户共享。 GPTs的创立过程GPTs的创立过程简略直观,用户能够通过对话模式为GPT提供指令和额定的知识库,而后抉择所需的能力,例如联网、绘图、剖析数据等。这使得GPTs可能适应各种场景,如教育、娱乐、数据分析等。OpenAI提供了GPTs商店,不便用户分享和应用不同的GPTs。 GPTs的利用前景GPTs的呈现,为集体开发者提供了疾速发明多样小型产品的可能性,这在以往通常须要程序员、产品经理和设计师的合作能力实现。通过GPTs,用户能够创立用于日常生活、特定工作、工作或家庭中的AI助手,晋升效率和便利性。例如,能够创立帮忙教孩子数学的GPTs,或者设计用于解释棋盘游戏规则的GPTs。 以下是依照您的要求转换成Markdown格局的内容: GPTs与微信小程序区别GPTs和微信小程序在概念上有肯定的相似性,但也存在显著的区别。以下是两者的比拟: 相似之处:定制化:GPTs容许用户依据本人的需要定制ChatGPT的性能,而微信小程序也容许开发者依据特定的业务需要创立应用程序。易于应用:GPTs和微信小程序都旨在为用户提供便捷的服务,用户无需下载安装即可应用。生态系统:OpenAI的GPTs商店相似于微信小程序平台,提供了一个生态系统,让开发者能够分享和推广本人的GPTs或小程序。区别:性能范畴:GPTs是基于大型语言模型的AI利用,次要提供基于文本的交互和信息处理能力,如对话、写作辅助、数据分析等。而微信小程序则提供了更宽泛的性能,包含但不限于电商、游戏、工具服务等。技术根底:GPTs依赖于OpenAI的GPT模型,次要解决自然语言解决(NLP)工作。微信小程序则基于微信平台,应用微信提供的API和开发框架,能够蕴含多种类型的交互和性能。开发者和用户:GPTs的创建者通常是心愿利用AI能力的用户或开发者,而微信小程序的开发者通常是企业或集体开发者,他们为微信用户提供服务或产品。应用场景:GPTs更多地用于提供信息、解答问题和执行基于文本的工作,而微信小程序则更多地用于商业交易、社交互动和其余类型的应用服务。总的来说,GPTs能够被视为一种特定于AI对话和文本处理的定制工具,而微信小程序则是一种更通用的利用平台,提供了更多样化的服务和性能。两者都是响应用户需要和提供便利性的工具,但它们的利用范畴和技术实现有所不同。 如何创立?1:点击摸索GPTs 2:创立我的GPTs 3:创立GPTs GPTs小红书案例 4:公布GPTs 总结GPTs能够让用户更为便捷的应用封装好的提醒词,不必每次再输提醒词了。 本文由mdnice多平台公布

March 3, 2024 · 1 min · jiezi

关于后端:服务发现CP-or-AP

1 服务发现的意义为高可用,生产环境中服务提供方都以集群对外提供服务,集群里这些IP随时可能变动,也须要用一本“通信录”及时获取对应服务节点,这获取过程即“服务发现”。 对服务调用方和服务提供方,其契约就是接口,相当于“通信录”中的姓名,服务节点就是提供该契约的一个具体实例。服务IP汇合作为“通信录”中的地址,从而可通过接口获取服务IP的汇合来实现服务的发现。即PRC框架的服务发现:RPC服务发现原理图 1.1 服务注册在服务提供方启动时,将对外裸露的接口注册到注册核心,注册核心将这个服务节点的IP和接口保留 1.2 服务订阅在服务调用方启动时,去注册核心查找并订阅服务提供方的IP,而后缓存到本地,并用于后续的近程调用 2 为何不应用DNS?服务发现的实质,就是实现接口跟服务提供者IP的映射。是否把服务提供者IP对立换成一个域名,利用DNS实现? 2.1 DNS流程DNS查问流程: 所有服务提供者节点都配置在同一域名下,调用方是可通过DNS拿到随机的一个服务提供者的IP,并建设长连贯,但业界为何不必这计划? 异样思考若该IP端口下线了,服务调用者是否及时摘除服务节点若在之前已上线一部分服务节点,忽然对这服务扩容,新上线的服务节点是否及时接管到流量都不能。为晋升性能和缩小DNS服务压力,DNS采取多级缓存,缓存工夫较长,尤其JVM默认缓存是永恒无效,所以服务调用者不能及时感知服务节点变动。 是否能加个负载平衡设施?将域名绑定到这台负载平衡设施,通过DNS拿到负载平衡的IP。服务调用时,服务调用方就能间接跟VIP建设连贯,而后由VIP机器实现TCP转发: VIP计划: 这是能解决DNS遇到的一些问题,但RPC里不是很适合: 搭建负载平衡设施或TCP/IP四层代理,需额定老本申请流量都通过负载平衡设施,多通过一次网络传输,节约性能负载平衡增加节点和摘除节点,个别要手动增加,当大批量扩容和下线时,会有大量人工操作和失效提早服务治理时,需更灵便的负载平衡策略,目前负载平衡设施的算法不满足灵便需要由此可见,DNS或者VIP计划尽管能够充当服务发现的角色,但在RPC场景外面间接用还是很难的。 3 基于zk的服务发现(CP)服务发现的实质:实现接口跟服务提供者IP的映射。就是一种命名服务,还心愿注册核心实现实时变更推送,zk、etcd都能实现。 搭建一个zk集群作为注册核心集群,服务注册时,只需服务节点向zk写入注册信息,利用zk的Watcher机制实现服务订阅与服务下发性能。 整体流程基于ZooKeeper服务发现结构图: 服务平台治理端先在zk创立一个服务根门路,可依据接口名命名(如:/service/com.javaedge.xxService),在这门路再创立服务提供方目录与服务调用方目录(如:provider、consumer),别离存储服务提供方、服务调用方的节点信息当服务提供方发动注册时,会在服务提供方目录中创立一个长期节点,节点中存储该服务提供方的注册信息当服务调用方发动订阅时,则在服务调用方目录中创立一个长期节点,节点中存储该服务调用方的信息,同时服务调用方watch该服务的服务提供方目录(/service/com.demo.xxService/provider)中所有的服务节点数据。当服务提供方目录下有节点数据产生变更时,zk告诉给发动订阅的服务调用方zk缺点晚期RPC框架服务发现就是基于zk实现,但后续团队微服务化水平越来越高,zk集群整体压力越来越高,尤其在集中上线时越发显著。“集中暴发”是在一次大规模上线时,过后有超大批量服务节点在同时发动注册操作,ZooKeeper集群的CPU飙升,导致集群不能工作,也无奈立马将zk集群重新启动,始终到zk集群复原后业务能力持续上线。 根本原因就是zk自身性能问题,当连贯到zk的节点数量特多,对zk读写特频繁,且zk存储目录达到肯定数量,zk将不再稳固,CPU继续升高,最终宕机。宕机后,因为各业务的节点还在继续发送读写申请,刚一启动,zk就因无奈接受霎时的读写压力,马上宕机。 要重新考虑服务发现计划。 4 音讯总线(AP)zk强一致性,集群的每个节点的数据每次产生更新操作,都告诉其它节点同时执行更新。它要求保障每个节点的数据实时完全一致,间接导致集群性能降落。 而RPC框架的服务发现,在服务节点刚上线时,服务调用方可容忍在一段时间后(如几s后)发现这个新上线的节点。毕竟服务节点刚上线后的几s内,甚至更长的一段时间内没有接管到申请流量,对整个服务集群没有什么影响,可就义掉CP(强制一致性),抉择AP(最终统一),换取整个注册核心集群的性能和稳定性。 是否有一种简略、高效,并且最终统一的更新机制,代替zk数据强统一的数据更新机制?最终一致性,可思考音讯总线机制。注册数据可全量缓存在每个注册核心的内存,通过音讯总线来同步数据。当有一个注册核心节点接管到服务节点注册时,会产生一个音讯推送给音讯总线,再通过音讯总线告诉给其它注册核心节点更新数据并进行服务下发,从而达到注册核心间数据最终一致性。 4.1 总体流程 服务上线,注册核心节点收到注册申请,服务列表数据变动,生成一个音讯,推送给音讯总线,每个音讯都有整体递增的版本音讯总线被动推送音讯到各注册核心,同时注册核心定时拉取音讯。对获取到音讯的,在音讯回放模块外面回放,只承受大于本地版本号的音讯,小于本地版本号的音讯间接抛弃,实现最终一致性消费者订阅可从注册核心内存拿到指定接口的全副服务实例,并缓存到消费者的内存采纳推拉模式,消费者可及时拿到服务实例增量变动状况,并和内存中的缓存数据进行合并。为性能,这里采纳两级缓存,注册核心和消费者的内存缓存,通过异步推拉模式确保最终一致性。 服务调用方拿到的服务节点不是最新的,所以指标节点存在已下线或不提供指定接口服务的状况,这时咋办?这问题放到RPC框架里解决,在服务调用方发送申请到指标节点后,指标节点会进行合法性验证,若指定接口服务不存在或正在下线,则回绝该申请。服务调用方收到回绝异样后,会平安重试到其它节点。 通过音讯总线,实现注册核心集群间数据变更的告诉,保证数据最终一致性,并能及时触发注册核心的服务下发。服务发现的个性是容许咱们在设计超大规模集群服务发现零碎的时候,舍弃强一致性,更多思考零碎健壮性。最终一致性才是分布式系统设计更罕用策略。 5 总结通常可应用zk、etcd或分布式缓存(如Hazelcast)解决事件告诉问题,但当集群达到肯定规模之后,依赖的ZooKeeper集群、etcd集群可能就不稳固,无奈满足需要。 在超大规模的服务集群下,注册核心所面临的挑战就是超大批量服务节点同时高低线,注册核心集群承受到大量服务变更申请,集群间各节点间须要同步大量服务节点数据,导致: 注册核心负载过高各节点数据不统一服务下发不及时或下发谬误的服务节点列表RPC框架依赖的注册核心的服务数据的一致性其实并不需要满足CP,只有满足AP即可。咱们就是采纳“音讯总线”的告诉机制,来保障注册核心数据的最终一致性,来解决这些问题的。 如服务节点数据的推送采纳增量更新的形式,这种形式进步了注册核心“服务下发”的效率,而这种形式,还可用于如对立配置核心,用此形式能够晋升对立配置核心下发配置的效率。 6 FAQ某大厂中间件的用户平台,服务挂了,在注册核心上还得手动删除死亡的节点,若是zk,服务没了,就代表会话也没了,长期节点应该会被告诉到把?为何还要手动删除? 长期节点是须要等到超时工夫之后才删除,不够实时。 如果要能切换流量,要服务端配置权重负载平衡策略,这样服务器端即可通过调整权重安顿流量。 服务消费者都是从注册核心拉取服务提供者的地址信息,所以要切走某些服务提供者数据,只须要将注册核心这些实例的地址信息删除(其实下线利用实例,理论也是去删除注册核心地址信息),而后注册核心反向告诉消费者,消费者受到拉取最新提供者地址信息就没有这些实例了。 通过服务发现来摘除流量是最常见的伎俩,还能够高低线状态、权重等形式。 现有开源注册核心是不是还没有音讯总线这种实现形式?音讯总线有没有开源实现? 现成MQ也可充当音讯总线。 音讯总栈相似一个队列,队列示意是递增的数字,注册核心集群的任何一个节点接管到注册申请,都会把服务提供者信息发给音讯总栈,音讯总栈会像队列以先进先出的准则推送音讯给所有注册核心集群节点,集群节点接管到音讯后会比拟本人内存中的以后版本,保留版本大的,这种形式有很强的实效性,注册核心集群也能够从音讯总栈拉取音讯,确保数据AP,集体了解这是为了避免音讯未接管到导致个别节点数据不精确,因为服务提供者能够向任意一个节点发送注册申请,从而升高了单个注册核心的压力,而注册和注册核心同步是异步的,也解决了集中注册的压力,在Zookeeper中,因为Zookeeper注册集群的强一致性,导致必须所有节点执行完一次同步,能力执行新的同步,这样导致注册解决性能升高,从而高I/O操作宕机。 当集中注册时,音讯总栈下发告诉给注册核心集群节点,对于单个节点也会不停的收到更新告诉,这里也存在高I/O问题,会不会有宕机?event bus能够革新成主从模式保障高可用。 AP实现中“两级缓存,注册核心和消费者的内存缓存,通过异步推拉模式来确保最终一致性的具体实现? 推次要实现callback,拉的动作在客户端。 音讯总线策略怎么保障音讯总线全局版本递增?最简略的用工夫戳。 音讯总线构建ap 型注册核心,不是很了解。是多个注册核心独立提供读写,他们之间通过音讯队列做数据同步?那么一致性感觉不好保障,比方服务a 先注册,再反注册,然而别离发到两个注册核心节点,最终同步可能是乱序的哇?个别不会呈现这种状况,只有连贯断开后,那须要从新注册。 音讯总线的另一个利用case:配置核心。 关注我,紧跟本系列专栏文章,咱们下篇再续! 作者简介:魔都技术专家兼架构,多家大厂后端一线研发教训,各大技术社区头部专家博主,编程严选网创始人。具备丰盛的引领团队教训,深厚业务架构和解决方案的积攒。 负责: 地方/分销预订零碎性能优化流动&优惠券等营销中台建设交易平台及数据中台等架构和开发设计 目前主攻升高软件复杂性设计、构建高可用零碎方向。 参考: 编程严选网 本文由博客一文多发平台 OpenWrite 公布!

March 3, 2024 · 1 min · jiezi

关于后端:maven-技巧实时更新快照乱码问题下载很慢包依赖解决包冲突如何导入本地-jar

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 实时更新快照当您在应用 Idea 获取 快照(snapshot) Jar 包时,您可能不能立刻取得它。 以下是解决办法: 关上 Preference,搜寻 maven,并抉择 Always update snapshots 乱码问题mvn运行乱码问题 在 pom.xml 的 properties 下增加以下内容: <properties> <argLine>-Dfile.encoding=UTF-8</argLine></properties>下载很慢blog zh_CN 在 ~/.m2/setting.xml 中增加: <mirrors> <!-- 阿里云仓库 --> <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror></mirrors>包依赖解决包抵触有时候依赖其余的三方jar包较多,有些jar被反复引入且版本不统一。(比方slf4j-api.jar) ...

March 3, 2024 · 2 min · jiezi

关于后端:maven-包管理平台05multi-module-多模块

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 多模块创立创立一个空的 Maven 我的项目,它的 pom.xml 如下所示: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ryo</groupId> <artifactId>multiModule</artifactId> <version>1.0-SNAPSHOT</version></project>为 multiModule 创立子模块 util,同时咱们以相似的形式创立另一个模块 dao: multiModule 的 pom.xml 将是:<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ryo</groupId> <artifactId>multiModule</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>util</module> </modules></project>util 模块的 pom.xml 如下:<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>multiModule</artifactId> <groupId>com.ryo</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>util</artifactId></project>在 util 模块中的 StringUtil.java 文件public class StringUtil { private static final String EMPTY_STRING = ""; private StringUtil(){} public static boolean isEmpty(String string) { return string == null || string.trim().equals(EMPTY_STRING); }}应用如果咱们想要在 dao 模块中应用 util 模块的 StringUtil.java,咱们应该依照以下步骤进行: ...

March 3, 2024 · 1 min · jiezi

关于后端:平台工程-用Backstage构建开发者门户-2

本文介绍了如何应用开源Backstage构建本人的开发者门户,并基于此实际平台工程。本系列共两篇文章,这是第二篇。原文: Platform Engineering: Building Your Developer Portal with Backstage — Part 2 在本教程第一局部中咱们理解了Backstage这个用于构建开发者门户的开源CNCF工具,还创立了一个软件模板,用于在GitHub中为疏导我的项目/存储库构建默认平安的软件组件。 本文将持续开发这一开发者门户,并将其带到下一个档次。 1. 应用PostgreSQL数据库1.1. Backstage数据库在本教程第一局部中,咱们理解到Backstage由前端和后端两局部组成。 如果略微用一下创立的门户,就会发现一旦重新启动yarn dev服务器,之前导入的组件将不再存在。 这是因为Backstage后端(及其插件)须要数据库来存储其状态。 注: Backstage次要针对两个数据库进行了测试,别离是SQLite(次要用作内存中的模仿/测试数据库)和PostgreSQL(首选的生产数据库)。其余数据库,如MySQL之类,据说能够工作,但没有通过残缺测试。因而,接下来咱们将配置Backstage应用PostgreSQL数据库。 1.2. 装置和配置PostgreSQL注: 如果曾经装置了 PostgreSQL 服务器并创立了schema和用户,能够跳过这些阐明。例如,你可能曾经在Linux服务器上通过apt-get装置了PostgreSQL,或者你可能在Docker容器甚至云数据库服务中运行PostgreSQL。上面的例子是针对Mac用户的。如果你不必Mac进行开发,PostgresSQL官网有对于如何装置PostgreSQL的具体阐明。 应用brew装置: brew install postgresql@14启动PostgreSQL并在登录时重新启动,运行: brew services start postgresql@14如果须要进行/重启,能够执行如下命令: brew services stop postgresql@14brew services restart postgresql@14运行psql postgres命令登录Postgres shell,应该能够看到欢送的交互式命令行,如下所示: tiexin@mbp ~/work/my-portal $ psql postgrespsql (14.8 (Homebrew))Type “help” for help.postgres=#在本教程中,咱们将创立用户"backstage",明码为"backstage",作为超级用户。请留神,这只实用于本地开发,而不适用于生产: postgres=# create user backstage with encrypted password ‘backstage’;CREATE ROLEpostgres=# alter role backstage with superuser;ALTER ROLE1.3. 配置Backstage应用PostgreSQL进入开发者门户目录的根目录,应用以下命令启动PostgreSQL客户端装置: ...

March 3, 2024 · 2 min · jiezi

关于后端:免备案零基础手把手教你从零搭建WordPress文末有视频教程

title: 免备案!零根底!手把手教你从零搭建WordPressdate: 2024-03-02top_img: https://gptcard.oss-cn-shanghai.aliyuncs.com/gptcard/Snipaste...cover: https://gptcard.oss-cn-shanghai.aliyuncs.com/gptcard/Snipaste... 服务器服务器购买本次教程的服务器相干的配置基于野草云 不太举荐购买境内服务器,倡议买香港/新加坡的 2h2g为根本,1g运行WordPress很容易卡死 配置选项如果是在其余的云服务器商购买,留神有些服务器可能会不给ipv4,还是举荐大家间接在野草云购买 服务器设置Root明码倡议提前设置好,缩小后续更改的麻烦 服务器的连贯与宝塔的装置从主页右上角【客户核心】-【产品服务】能够看到所购买服务器的IP(前面有用) 点击上图大红色方框,进入后先将服务器开机 服务器连贯常用工具Putty:https://www.putty.org/Mobaxterm:https://mobaxterm.mobatek.net/download.html MobaXterm 应用 先点击左上角的【session】-在跳出的界面典籍【SSH】-而后将服务器的IP填入【Remote host】中 点击OK 先会跳出【login as】:输出【root】而后回车,会提醒输出明码明码即为购买服务器的时候设置的明码,输出明码的时候不会显示,输出完按回车即可 这条提醒为记住明码,能够选YES,后续在MobaXterm连贯的时候就免去输出明码了 宝塔的装置宝塔主页:https://www.bt.cn/new/index.html Ubuntu/Deepin装置脚本wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ed8484bec 将上方的命令粘贴到窗口,并按回车(在MobaXterm中鼠标右键一次,应该就能够粘贴下来) 期待装置实现即可 放行宝塔后盾端口在装置实现之后能在窗口看到后盾的登录端口,或者输出bt-回车再输出14,即可查看面板的默认信息 而后关上野草云后盾,点击左侧【防火墙规定】-而后点击增加 增加的内容如图所示,指标端口依照宝塔后盾提醒的填写,每台服务器都不一样!而后记得启用 这样就能通过面板地址拜访啦!(登陆的账号密码都能够在命令行端口输出【bt】,而后输对应的选项进行批改) 进入之后插件抉择装置LNMP,期待装置实现即可持续下一步 装置WordPress 按如上图所示设置,确定即可,如果还没有购买域名,能够先购买域名,购买教程在本教程后半局部 期待装置 点击拜访站点,进行WordPress的初始化设置 域名域名购买不倡议买境内云服务商的域名,须要备案,并且有肯定周期 如果前期要做SEO(搜索引擎优化Search Engine Optimization)买.com域名 GoDaddy:https://www.godaddy.com/ NameCheap:https://www.namecheap.com/ 在Godaddy购买的话反对paypal或者其余信用卡得领取(wildcard当然也能够用) 托管到CloudflareCloudflare:https://www.cloudflare.com/zh-cn/ 关上Cloudflare,增加域名 在概述这向下拖动,能看到Cloudflare调配的名称服务器 而后在Godaddy购买得域名治理中,点击【DNS】-【域名服务器】-【更改域名服务器】,而后将Cloudflare调配的服务器填入 期待约30min-60min,在cloudflare页面刷新,呈现下图就阐明设置实现。 域名解析在Cloudflare增加记录 ...

March 3, 2024 · 1 min · jiezi

关于后端:Rust中channel的使用

对于Rust中的channel Rust的channel是一种用于在不同线程间传递信息的通信机制,它实现了线程间的消息传递。 Channel容许在Rust中创立一个消息传递渠道,它返回一个元组构造体,其中蕴含发送和接收端。发送端用于向通道发送数据,而接收端则用于从通道接收数据。每个channel由两局部组成:发送端(Sender)和接收端(Receiver)。 发送端用于向channel发送音讯,而接收端则用于接管这些音讯。这种机制容许线程之间的平安通信,防止了共享内存的复杂性和潜在的数据竞争问题。 (通过通信来共享内存,而非通过共享内存来通信) Rust的channel为线程间通信提供了一种平安、简略的形式,是构建并发利用的根底工具之一。 channel是Rust规范库的一部分,自Rust 1.0版本以来就蕴含了这个性能。随着Rust语言和规范库的倒退,channel的实现和API可能会有所改进,但其基本概念和用法保持一致。 应用形式 根本步骤如下: 创立: 应用std::sync::mpsc::channel()函数创立一个新的channel,这个函数返回一个蕴含发送端(Sender)和接收端(Receiver)的元组。发送: 应用发送端的send办法发送音讯。send办法承受一个音讯值,如果接收端曾经被抛弃,会返回一个谬误。接管: 应用接收端的recv办法接管音讯。recv会阻塞以后线程直到一个音讯可用,或者channel被敞开。示例以下是一个应用channel在两个线程间发送和接管音讯的简略例子: use std::sync::mpsc;use std::thread;fn main() { // 创立一个channel let (tx, rx) = mpsc::channel(); // 创立一个新线程,并向其中发送一个音讯 thread::spawn(move || { let msg = "Hello from the thread"; tx.send(msg).unwrap(); println!("Sent message: {}", msg); }); // 在主线程中接管音讯 let received = rx.recv().unwrap(); println!("Received message: {}", received);} 下面例子展现了channel的根本办法:先创立一个channel,而后在一个新线程中发送一个字符串音讯,并在主线程中接管这个音讯。 留神: 发送端tx通过move关键字挪动到新线程中,这是因为Rust的所有权规定要求确保应用数据的线程领有该数据的所有权。 对于MPSC 其中mpsc是Multi producer, Single consumer FIFO queue的缩写,即多生产者单消费者先入先出队列 Rust规范库提供的channel是MPSC(多生产者,单消费者)模型,这意味着能够有多个发送端(Sender)向同一个接收端(Receiver)发送音讯。这种模式十分实用于工作队列模型,其中多个生产者线程生成工作,而单个消费者线程解决这些工作。 ...

March 2, 2024 · 2 min · jiezi

关于后端:使用cargo-edit管理Rust项目的依赖

介绍 大略因为IDE还不够智能&弱小,在Rust中每次须要引入依赖时,都须要手工增加到Cargo.toml文件中,而且版本号还要去crates下面去查 (这个通过装置插件,能够给出提醒版本) 而cargo-edit能够主动帮忙增加依赖,且自动更新版本号 cargo-edit是一个很好用的工具,扩大了Cargo的性能,容许通过命令行批改Cargo.toml文件来增加、移除和降级依赖。 cargo-edit包含几个子命令,如cargo upgrade、cargo add和cargo rm等。 其中,cargo add,cargo rm曾经在最新的cargo中集成。 cargo upgrade用于将Cargo.toml中的依赖降级到其最新版本,并提供了不同的降级选项。 cargo set-version用于在Cargo.toml中设置版本号,能够通过指定版本号或主动减少主版本、次版本或修订版原本应用。 如果没有装置cargo-edit,能够通过cargo install cargo-edit 进行装置 如果有如下报错: error: linking with `cc` failed: exit status: 1 | = note: env -u IPHONEOS_DEPLOYMENT_TARGET -u TVOS_DEPLOYMENT_TARGET LC_ALL="C" PATH="xxxxxx(一大堆PATH门路)" = note: Undefined symbols for architecture arm64: "_iconv", referenced from: _git_fs_path_iconv in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) (maybe you meant: _git_fs_path_iconv_clear, _git_fs_path_iconv_init_precompose , _git_fs_path_iconv ) "_iconv_close", referenced from: _git_fs_path_direach in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) _git_fs_path_iconv_clear in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) _git_fs_path_diriter_free in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) "_iconv_open", referenced from: _git_fs_path_direach in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) _git_fs_path_iconv_init_precompose in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) _git_fs_path_diriter_init in liblibgit2_sys-d72cdefc619e6458.rlib(fs_path.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) error: could not compile `cargo-edit` (bin "cargo-upgrade") due to previous errorerror: failed to compile `cargo-edit v0.12.2`, intermediate artifacts can be found at `/var/folders/9t/839s3jmj73bcgyp5x_xh3gw00000gn/T/cargo-installhdtjjF`.To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.可应该是arm64上特有的问题,可依照 cc failed: exit code: 1">error: linking with cc failed: exit code: 1来操作, ...

March 2, 2024 · 1 min · jiezi

关于后端:maven-archetype-项目原型

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 Maven Archetypearchetype是什么?简而言之,Archetype 是一个 Maven 我的项目模板工具包。原型被定义为所有雷同类型的其余事物所制作的原始模式或模型。 应用要基于原型创立新我的项目,您须要调用 mvn archetype:generate 指标。 如何创立原型?创立定义原型创立$ mvn archetype:create-from-projecthoubinbindeMacBook-Pro:archetype houbinbin$ mvn archetype:create-from-project[INFO] Scanning for projects...[INFO][INFO] ------------------------------------------------------------------------[INFO] Building archetype 1.0.0[INFO] ------------------------------------------------------------------------[INFO][INFO] >>> maven-archetype-plugin:2.4:create-from-project (default-cli) > generate-sources @ archetype >>>[INFO][INFO] <<< maven-archetype-plugin:2.4:create-from-project (default-cli) < generate-sources @ archetype <<<[INFO][INFO] --- maven-archetype-plugin:2.4:create-from-project (default-cli) @ archetype ---[INFO] Setting default groupId: com.ryo[INFO] Setting default artifactId: archetype[INFO] Setting default version: 1.0.0[INFO] Setting default package: com.ryo[INFO] Scanning for projects...[INFO][INFO] ------------------------------------------------------------------------[INFO] Building archetype-archetype 1.0.0[INFO] ------------------------------------------------------------------------[INFO][INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ archetype-archetype ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 10 resources[INFO][INFO] --- maven-resources-plugin:3.0.1:testResources (default-testResources) @ archetype-archetype ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 2 resources[INFO][INFO] --- maven-archetype-plugin:2.4:jar (default-jar) @ archetype-archetype ---[INFO] Building archetype jar: /Users/houbinbin/IT/code/branches/archetype/target/generated-sources/archetype/target/archetype-archetype-1.0.0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 0.835 s[INFO] Finished at: 2016-06-11T21:57:36+08:00[INFO] Final Memory: 14M/309M[INFO] ------------------------------------------------------------------------[INFO] Archetype project created in /Users/houbinbin/IT/code/branches/archetype/target/generated-sources/archetype[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 2.955 s[INFO] Finished at: 2016-06-11T21:57:36+08:00[INFO] Final Memory: 14M/245M[INFO] ------------------------------------------------------------------------装置$ cd target/generated-sources/archetype/$ mvn install日志 ...

March 2, 2024 · 3 min · jiezi

关于后端:maven-项目的创建入门

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 创立 Maven 我的项目您能够像这样在 IntelliJ IDEA 中创立 Maven 我的项目: File -> New -> Module -> Maven步骤 1:从原型中抉择一个步骤 2:增加 GroupId、ArtifactId、Version步骤 3:设置属性如果 Maven 构建十分迟缓,您能够增加以下代码:archetypeCatalog=internal运行我的项目在命令行中的优雅形式mvn clean installmvn tomcat7:run惯例形式Tomcat 中文文档 提醒设置您能够应用以下步骤配置 Maven 设置,而后搜寻 maven 快捷键:ctrl+alt+s ...

March 2, 2024 · 1 min · jiezi

关于后端:网狐核心源码阅读分析

框架结构网狐服务器整体上分为4个局部:直达服务器,房间服务器,大厅服务器,sqlserver数据库。其中大厅服务器次要负责帐号管理器:治理用户抉择服务器登录地址,校验用户数据等。必须与直达服务器放弃长连贯,用于更新获取最新数据。房间服务器:用于加载解决每款子游戏逻辑与公共游戏逻辑(例如机器人整体随机进出任何游戏房间,机器人游戏信息处理等。他也必须与直达服务器放弃长连贯,用于传输最新游戏房间信息给直达服务器。直达服务器:收集所有房间服务和大厅服务器的ip、端口、在线游戏人数等信息,并负责直达全局的游戏音讯,所有房间服务器大厅服务器都在线连贯直达服务器,定时更新状态。直达服务器通过连贯平台库,获取平台的信息。同时这三个服务器又别离和数据库进行连贯,能够独立进行操作对应的数据库。这三个服务器都是依赖于爱玩内核而设计,能够看做是基于爱玩内核对不同业务需要的不同实现。 框架结构图 大厅服务器启动流程:点击启动服务按钮调用OnBnClickedStartService()函数,调用StartService()函数进行初始化配置信息:在StartService()函数里先加载配置信息,配置信息包含初始化用户数据库,财产数据库,站点页面,过程以后启动目录,相干配置文件门路名称,获取本地ip,直达服务器信息等,而后配置数据库信息,设置最大连接数为2048,监听端口,udp监听端口。创立必要组件:m_TimerEngine定时器引擎(用于做脉冲心跳定时获取与核心服务器的最新列表信息)m_DataBaseEngine数据库引擎(解决业务层投递信息,解决写入数据库)m_AttemperEngine调度引擎(用于解决业务)m_TCPNetworkEngine网络引擎服务m_TCPSocketTransfer 外部网络服务 创立数据库引擎和调度引擎的回调钩子函数,并且和数据库引擎调度引擎的钩子函数成员变量绑定。这样绑定是为了引擎能调用钩子函数。把调度引擎顺次和工夫引擎,外部网络服务,网络引擎外部的事件接口成员变量绑定,这样绑定是为了其余引擎解决完本人的工作后能把工作投递到调度引擎。把网络引擎和调度引擎外部的网络接口成员变量绑定,这样做惟一目标是当调度引擎解决网络引擎投递过去的工作失败时,能敞开对应的socket句柄。把调度引擎回调钩子函数的配置参数,事件引擎,数据库引擎,网络引擎,外部网络服务顺次初始化为下面创立的组件。这样绑定后重写的调度回调钩子函数就能调用内核引擎来解决工作。始化数据库回调钩子函数的配置参数,事件接口。这样数据库引擎操作完数据库后,能够把后果投递给调度引擎。络引擎的最大连接数,监听端口,设置好工作目录。读取内核设置,查看并创立内核日志、大厅日志目录,而后顺次启动工夫引擎,外部网络服务,数据库引擎,调度引擎,网络引擎,UDP引擎。大厅服务器次要性能: 次要性能包含:解决玩家注册,登录大厅过程中获取一系列包含,用户材料、头像、银行信息、账号密码,工作处分,零碎赠送,用户成就和是否代理,是否绑定推广,等辅助信息系统赠送等等所有用户在咱们游戏中的个人信息定时查看与直达服务器的长连贯信息,每隔30s向直达服务器发送一次SUB_CS_GET_SERVER_LIST音讯用于更新列表信息,包含游戏类型信息,游戏品种信息,房间信息,如果开启网关,还有网关信息。定期更新的这些游戏服务器信息,会在玩家登陆胜利后发送给客户端3.解决创立桌子流程4.解决创立俱乐部,查找俱乐部,删除俱乐部,复制俱乐部,批改俱乐部,降级俱乐部,增加俱乐部成员等等与俱乐部相干性能5.解决玩家玩家批改个人资料,银行信息,实名认证,手机绑定相干性能6.解决玩家游戏工作性能7.解决用户成就性能8.游戏商城性能 创立房间流程玩家点击创立房间或者退出房间按钮,客户端给大厅服务器发送MDM_GP_USER/SUB_GP_TABLE_QUERY_ONLINE也就是用户信息/查问在线信息,服务执行GSP_GP_QueryOnline存储过程查问用户状况,查问后果返回给客户端,客户端依据查问后果,从而让客户端判断玩家是走创立房间,退出房间还是走断线重连流程。如果是创立房间流程,会弹出创立房间界面,玩家抉择好要开房的游戏后,发送MDM_GP_USER/SUB_GP_TABLE_CREATE用户信息/创立桌子信息给大厅服务器,大厅服务器发送MDM_CS_PRIVATE_TABLE_MANAGE/SUB_CS_TABLE_CREATE私人房桌子/创立桌子音讯给直达服务器如果房间创立胜利,会收到来自直达服务器的MDM_CS_PRIVATE_TABLE_MANAGE//SUB_CS_TABLE_CREATE_SUC私人房桌子/创立胜利音讯。而后大厅把这个音讯发送给客户端,客户端坐下后会收到来自直达服务器的私人房桌子/刷新桌子信息音讯,同时大厅也会把这条音讯批量转发给客户端综合以上流程能够看出:在直达服务器和游戏服务器没启动时,只有大厅服务器启动,玩家就能够登陆到大厅,只是玩家点击创立房间时,因为没有直达服务器,所以玩家在发送创立房间信息时,音讯不能通过直达服务器转发给游戏服务器,所以也就创立失败,同时如果启动直达服务器,但不启动游戏服务器,当中转服务器收到大厅服务器的建房音讯后,会创立失败,而后返回创立失败音讯给大厅服务器,大厅服务器也会返回给客户端创立失败后果。 登陆大厅流程依据客户端不同登陆申请,在OnSocketMainLogon()函数里别离有账号登陆,微信登陆,注册账号,账号重连,微信重连这些不同解决流程只看微信登陆这条流程 投递DBR_LOGON_WX数据库申请后执行GSP_GP_LogonWX存储过程进行参数校验,校验胜利后会获取DBR_LogonSuccess这个构造体所有用户相干信息,接着投递DBR_LOGON_SUCCESS这个申请,紧接着会依投递数据库申请取得辅助信息,签到信息,首充信息,明码信息,布告信息,会员信息,登录胜利后会发送CMD_GP_LogonSuccess这个构造体所有信息,和房间列表,播送音讯等给客户端到此玩家登录大厅胜利 直达服务器启动流程从CCenterService::StartService()这个函数启动,初始化网络设置,配置好PlatformDB平台数据库相干参数,创立数据库引擎,调度引擎,网络引擎,定时器引擎,创立好组件接口,并把这些组件和内核绑定,设置好数据库引擎和调度引擎的回调钩子,配置网络引擎参数,包含设置好以服务端口为文件名的内核日志文件,设置好内核设置配置文件,建设内核日志目录。而后顺次启动工夫引擎,网络引擎,数据库引擎,调度引擎。 启动网络引擎:会对实现端口进行一些初始化,并且启动异步引擎服务,配置好读写线程,应答线程,检测线程,并且启动这些线程,将服务设置为启动状态。启动数据库引擎:线程启动函数CServiceThread::ThreadFunction执行,调用OnEventThreadStrat(),OnEventThreadStrat()又调用OnAsynchronismEngineStart()启动异步引擎,在异步引擎启动时会调用异步引擎钩子函数的启动函数OnDataBaseEngineStart()。启动调度引擎:创立列表组件,并且设置好数据库信息,俱乐部数据库信息,加载列表,读取私人房、俱乐部配置,加载限度字符, 直达服务器次要性能1.每隔60s删除一次私人房,每隔180s更新一次私人房间配置,每隔5s查看一次俱乐部主动开房2.收到大厅服务器更新列表申请时,向大厅服务器返回品种列表,房间列表,网关列表,等信息3.解决来自大厅的创立桌子,查找桌子,删除桌子,解决来自房间服务的玩家坐下,游戏开始,玩家起立,游戏完结,游戏扣钻等音讯4.解决来自web服务的写分,充值,兑换,web转账,流动处分,兑换房卡等音讯5.解决来自大厅的俱乐部治理相干的申请6.房间服务启动时,解决同步私人房信息,注册房间,同步人数等申请,房间服务敞开时,解决登记房间申请 创立房间到房间遣散敞开流程玩家点击创立房间,直达服务器会收到来自大厅的MDM_CS_PRIVATE_TABLE_MANAGE/SUB_CS_TABLE_CREATE私人房桌子/创立桌子申请,在对建房参数做一系列查看后,会给大厅发送SUB_CS_TABLE_CREATE_SUC房间创立胜利音讯,接着直达服务器会收到来自游戏服务的SUB_CS_USER_SIT_DOWN玩家坐下音讯。 其余玩家输出房号退出房间后会收到来自大厅服务的SUB_CS_TABLE_FIND查找房号音讯,直达服务器会做参数查看,判断是否已在私人房,桌子是否存在,是否曾经开始游戏,是否人数已满,房卡是否足够等条件,如果所有查看通过,会发送SUB_CS_TABLE_FIND_SUC查找房间胜利音讯,接着也会收到来自房间服务的玩家坐下音讯房间遣散胜利后,会收到来自房间服务的所所有玩家的SUB_CS_USER_STAND_UP玩家起立音讯,和SUB_CS_TABLE_ENDGAME游戏完结音讯。 房间服务器初步意识通过查看整个服务器工程,发现房间服务源码文件是最多的,通过这些源码文件命名,和预览源码,能够看到房间服务器总体上能够分为:机器人包含机器人治理模块,调度模块,因为调度模块性能较多,所以分为通用,AI,银行,直达服务,网关,较量,移动用户,道具金币,工作,定时器这几个文件来写,还有数据库模块,启动模块,房间服务接口定义模块,局数工作模块,还有针对不同较量类型的功能模块,回放模块,性能测试模块,异步引擎,还有游戏桌子框架模块,发送post,request申请的web模块。同时,房间服务还包含房间加载模块 启动流程 点击启动房间按钮后,OnBnClickedStart函数会执行,初始化配置参数,能够看到房间服务会和AccountsDB,PlatformDB,TGGameScoreDB这3个数据库有分割,进入到CGameService::StartService()函数,首先启动日志服务,接着别离创立工夫引擎,调度引擎,网络引擎,直达服务引擎,同步引擎,数据库引擎,而后调整参数,给配置变量赋值,而后加载游戏服务模块组件,进入到InitializeService函数.配置组件:在配置组件时能够看到有大小为5的CDataBaseSinkPrimary和大小为3的CDataBaseSinkAssistant2个数据库引擎钩子数组.其中CDataBaseSinkPrimary次要用来解决和玩家相干的数据库操作,比方写分,银行等.因为这些操作须要保障程序性,所以必须放在同一个解决数组外面.而CDataBaseSinkAssistant次要用来解决不须要程序要求的零碎申请音讯.绑定组件,绑定组件的时候,能够看到解决零碎申请的数据库操作引擎只有1个,然而设置了3个数据库引擎钩子,而解决玩家相干操作的数据库引擎有5个,同时每个引擎都设置一个数据库引擎钩子.而后就是把解决玩家申请的数据库引擎和引擎钩子和同步引擎绑定.而后就是别离初始化CDataBaseSinkPrimary和CDataBaseSinkAssistant数组,设置他们须要操作的数据库以及一些其余绑定,留神到CDataBaseSinkPrimary绑定了同步引擎而而后顺次启动工夫引擎,网络引擎,同步引擎,内核数据库引擎,记录数据库引擎,调度引擎和网络引擎。内核数据库引擎启动:内核数据库引擎有5个同样的数据库引擎钩子,所以会启动5个同样的线程,在钩子函数的启动函数CDataBaseSinkPrimary::OnDataBaseEngineStart()里会连贯用户数据库,和提高数据库.记录数据库引擎启动:记录数据库引擎有3个同样的数据库引擎钩子,会启动3个同样的线程,在钩子含税启动函数里会连贯用户数据库和金币数据库.内核数据库引擎和记录数据库引擎启动不同点:尽管都是连贯了用户数据库和金币数据库,然而内核数据库是一共有5个数据库引擎,每个数据库引擎一个钩子函数,一个异步线程来解决工作,也就有是说这5个数据库引擎期待在5个不同的实现端口上,而记录数据库引擎是一个数据库引擎,然而有3个异步线程,这3个异步线程期待在同一个实现端口上.调度引擎启动:初始化变量,设置聊天,判断是银行领取还是,金币领取,如果是较量,会创立较量变量,创立玩家连贯信息变量,能够看到最大520个玩家用户,256个机器人用户,调用子游戏服务中的RectifyServiceOption函数,在子游戏逻辑代码里对房间参数进行批改,而后创立并初始化所有游戏桌子,初始化机器人治理类,而后依据房间类型参数来对列表项形容构造进行不同初始化,而后连贯直达服务器,而后顺次设置了限度音讯,零碎音讯,心跳检测,加载配置,加载游戏工作等定时器读取AI配置,加载机器人,加载工作,设置加载机器人定时器,加载银行,桌子框架加载配置。 房间服务次要性能解决直达服务器创立完房间后来自客户端的坐下,旁观申请。解决房间遣散或游戏完结后删除房间,玩家来到房间等流程对所有桌子的治理,散发不同桌子的游戏音讯到对应桌子玩家。播送桌子音讯到同桌子其余玩家。还有解决一些客户端和游戏服务器之间的处分,流动,等交互玩家游戏完结后,解决对玩家写分,金币等数据库操作。较量性能定时更新整个房间服务的服务器信息,网关信息,私人房信息到直达服务器。对机器人的治理其余性能内核引擎剖析异步引擎异步引擎工作流程实例能够说整个内核能高效的进行网络传输和数据库操作,都是依赖于异步引擎,查看异步引擎头文件,有异步引擎类CAsynchronismEngine和异步引擎线程类CAsynchronismThread,异步引擎线程类继承自服务线程CServiceThread,在整个内核中有数据库引擎,调度引擎,网络引擎,这三个用到了异步引擎,通过大厅服务启动过程中网络引擎的启动,来阐明异步引擎的作用。首先通过m_TCPNetworkEngine->StartService()这个函数进入到网络引擎启动,先是创立了一个实现端口,容许机器外围个数到线程来运行,而后就是socket编程的绑定,监听操作,接着通过SetAsynchronismSink函数创立指定个数的异步线程,并且通过SetAsynchronismEngineSink函数把异步线程的回调函数和启动异步引擎的引擎服务的钩子函数绑定或者引擎服务本身绑定。网络引擎是创立了1个异步线程,并且绑定了这个异步线程的m_pIAsynchronismEngineSink回调接口为网络引擎本身。而后执行CAsynchronismEngine::StartService()启动异步引擎, 创立实现端口,并且之前创立了多少个异步线程,这个实现端口就容许几个线程运行,并且把每个异步线程都和创立的实现端口绑定,而后就启动StartThread函数每个线程 通过tagThreadParameter构造体,把主线程指针,也就是该线程本人,传递到子线程到入口函数ThreadFunction中,同时通过事件变量让主线程挂起,进入到子线程入口函数ThreadFunction中,又通过tagThreadParameter构造体,拿到传入到参数,进入到CAsynchronismThread::OnEventThreadStrat()函数, 因为此时m_pIAsynchronismEngineSink绑定到了网络引擎,所以实际上调用到时网络引擎的OnAsynchronismEngineStart函数。设置事件变量,好让主线程从新执行。接着进入到线程执行函数, 到这里,异步线程就在循环里一直查看实现端口状态是否有网络操作达到。当有事件实现时,会利用临界区来对线程进行同步,避免多个线程操作队列数据。 异步引擎总结通过以上剖析能够看到应用异步引擎有几个重要步骤:先执行SetAsynchronismSink函数,将异步引擎要服务的模块和异步引擎绑定,在这个函了数中,创立了模块指定的个数的异步线程,也能够看做是工作线程,同时把每个线程都和模块绑定,也就是初始化异步引擎的的m_AsynchronismThreadArray线程对象数组,执行StartService启动异步引擎,先是创立一个实现端口,并且把它和每个异步线程绑定,而后调用StartThread启动每个异步异步线程。在线程启动函数里,创立线程参数,tagThreadParameter构造体,通过这个构造体传递了本线程本人的线程指针,用来标记线程是否启动胜利的标记,以及一个用来保障把cpu工夫片执行权限让给子线程的事件句柄。进入到ThreadFunction线程函数,先是调用重写了CServiceThread类的OnEventThreadStrat函数,在异步线程的OnEventThreadStrat函数中,会调用第一步绑定好了的异步线程的回调钩子函数m_pIAsynchronismEngineSink,进入到对应的被绑定的服务中的OnAsynchronismEngineStart函数。做一些服务模块自定义的启动初始工作。接着调用setEvent函数设置主线程创立的事件信号,这样主线程能够持续往下执行。而后在子线程里用一个除非执行返回为false才跳出的while循环来循环执行线程的运行函数RepetitionRun,在异步线程的运行函数里,是期待在实现端口的GetQueuedCompletionStatus函数上,这个函数会让异步线程进入到不占用cpu的睡眠状态,直到实现端口上呈现须要解决的网络操作或者超出设定的等待时间限度为止。能够看到异步引擎应用的是应用指定个数的工作线程来为其余模块服务,其余模块能够把工作交给异步线程,在异步线程里期待在在实现端口上,这样就不会让主线程阻塞。能够把异步引擎看做是具体对专为应用实现端口而设计的线程性能类 网络引擎启动实例1.通过大厅服务器启动过程来看网络引擎的启动,通过函数CTCPNetworkEngine::StartService()启动网络引擎,能够看到先是创立了一个容许机器cpu外围个数线程调度的实现端口,这个就是网络引擎的主实现端口。而后就是调用和实现端口配套的函数,创立绑定,设置监听socket。2.在异步引擎里启动网络引擎,并且只设置了一个工作线程。通过上面对异步引擎剖析,异步引擎本人会启动一个实现端口,最终网络引擎在异步引擎里运行,期待挂起在实现端口实现告诉函数上。3.创立外围个数读写线程保留到网络引擎的读写线程数组m_SocketRWThreadArray中,接着初始化应答线程,把应答线程与下面创立的主实现端口,监听socket,以及网络引擎指针绑定。 启动每个读写线程,最终也是期待挂起在主实现端口的GetQueuedCompletionStatus函数上,读写线程重写了父类线程RepetitionRun运行函数,在运行函数里有实现告诉到来时先是对重叠IO和单句柄数据也就是连接子项类进行一些查看。5.当实现告诉到来时,用CONTAINING_RECORD宏获取重叠io对应的数据包,而后依据数据包的类型进行解决。6.数据发送:进入到CTCPNetworkItem::OnSendCompleted函数,因为是实现端口,所以看这个函数前,先看一下CTCPNetworkItem::SendData发送数据函数,其中有一个GetSendOverLapped函数用来获取发送重叠IO构造,能够看到优先应用m_OverLappedSendActive重叠构造发送数据,不够用或者残余可用长度不够时就用m_OverLappedSendBuffer重叠构造,最初才应用new来创建对象。这样能够保障服务器运行过程中根本不调用new开拓内存,防止产生内存碎片。能够看到一次最大发送2046个字节数据。接着进行加密,封包,而后应用WSASend函数,投递异步发送申请。 接下来再看CTCPNetworkItem::OnSendCompleted函数,先是开释掉上一次发送用的重叠IO构造,并且保留到m_OverLappedSendBuffer缓冲重叠构造中,如果还有须要发送的数据,就再次投递异步发送申请。数据接管:进入CTCPNetworkItem::OnRecvCompleted函数,同样看接收数据要先看是如何投递连贯申请的,咱们通过看接管重叠IO的数据结构定义,发现并未提供接收数据的内存,构造函数里WSABUF接收缓冲区指针也是间接指向NULL,第一个接收数据申请是在应答线程里投递的,前面会提到。 正因为如此,所以在接管数据处理时,是间接调用阻塞的recv函数来从读取数据,接管完后就是对数据进行查看,做粘包拆包解决,而后再进行校验,最初非法的残缺数进入到网络引擎的CTCPNetworkEngine::OnEventSocketRead函数,这个函数再调用事件接口的OnEventTCPNetworkRead函数,让调度引擎进行解决。接着启动检测线程,每隔10s对所有和网络引擎连贯的socket进行心跳,非法检测。接着启动应答线程,在应答线程的线程运行函数里,调用的是WSAAccept函数,这个阻塞函数也会让应答线程挂起。当有连贯申请到来时,先判断最大连接数,而后创立新的连接子项,并与之绑定好新连贯的ip、socket,而后把他和主实现端口绑定。接着投递一个异步承受数据申请9.留神用WSARecv,WSASend投递异步收发数据申请时,WSA_IO_PENDING示意数据暂且还没收或者发送结束,须要期待后续告诉,所以也不能执行敞开socket操作。 网络引擎总结通过以上剖析,发现网络引擎读写线程和应答线程绑定的是同一个实现端口,采取的是单线程解决socket接入,多线程解决数据收发,检测线程是另外一个线程。发送数据是异步,接收数据尽管收到告诉应用了实现端口,然而投递的接收数据申请应用0缓冲区,而后期待有实现告诉时,再真正接收数据,搜寻网上材料,说这种设计是因为投递申请后,会锁定缓冲区内存,即便你 WSARecv 的缓存大小是 1 字节, 被锁定的内存也将会是 4k. 非分页内存池是由整个零碎共用的, 如果用完的话最坏的状况就是零碎解体。应用0内存,所以就不会被锁定,然而这样读数据效率必定会升高。 另外尽管独自启动了一个线程用来解决接入申请,然而效率应该不会比投递异步的acceptEX申请去接入效率高。 调度引擎启动实例还是以大厅服务器的调度引擎启动过程阐明:调度引擎启动很简略,应用一个工作线程的异步引擎绑定本人,而后启动异步引擎。 异步引擎启动后,在调度引擎的异步引擎启动函数CAttemperEngine::OnAsynchronismEngineStart()中,调用调度钩子函数启动函数,在调度钩子启动函数中,先把网络引擎和房间列表绑定,而后用外部网络服务连贯直达服务。 当有实现告诉到来时,会进入到CAttemperEngine::OnAsynchronismEngineData函数,能够看到在这里解决了来自内核其余引擎服务的所有音讯。 调度引擎总结调度引擎是解决整个内核所有音讯的调度核心,只管网络引擎,数据库引擎,工夫引擎,TcpSocket服务都至多各自占用一个线程,他们都独立工作,然而最终解决这些音讯的还是调度引擎一个线程。调度引擎能解决来自其余引擎的音讯,是因为在初始化时,其余须要投递音讯给调度引擎解决的线程都绑定了调度引擎的事件接口,当其余引擎本人线程解决完本人的工作后,通过事件接口回调调度引擎的异步线程的CAsynchronismEngine::PostAsynchronismData函数,通过实现端口的PostQueuedCompletionStatus函数被动投递实现告诉。总的来看其余引擎相当于生产者,调度引擎相当于消费者,期间应用了数据队列来替换数据,保障音讯的先进先出,应用临界区锁来进行线程同步保障队列的音讯精确的被某一个线程解决。察看到异步引擎在从队列拿音讯时,只对拿的过程进行爱护,并不是解决完一条音讯后加锁,能够想到在写业务逻辑时,是须要思考到函数是否重入的。如果客户端以很快的速度发送多条同样的音讯,这时候服务器可能会出问题。 TcpSocketService外部网络服务启动流程通过大厅服启动来阐明:外部网络服务外部有一个重写的CTCPSocketServiceThread网络线程类,外部网络服务启动时,间接启动了网络线程。 在线程启动函数CTCPSocketServiceThread::OnEventThreadStrat()里,创立了一个窗口句柄,窗口不显示。 而后再线程运行函数里,会调用阻塞的GetMessage函数让线程挂起直到有音讯到来。 同时在调度引擎的异步引擎启动函数CAttemperEngineSink::OnAttemperEngineStart里,会应用CTCPSocketService::Connect函数,给外部网络服务网络线程绑定的窗口句柄投递一个连贯申请。此时会在网络线程的线程运行函数里解决音讯。调用CTCPSocketServiceThread::PerformConnect执行连贯申请。 在执行函数CTCPSocketServiceThread::PerformConnect里![Uploading file...]()建设socket,并调用WSAAsyncSelect函数,把socket设置为非阻塞模式,并且绑定socket和窗口句柄,以及注册感兴趣的事件类型。这样当socket上有感兴趣事件到来时,WM_SOCKET_NOTIFY音讯就会发送给m_hWnd窗口句柄,在线程运行函数里解决。 外部网络服务总结1.应用外部网络服务发送数据:通过调用CTCPSocketService::SendData函数,这个函数有2个版本一个发送不带数据音讯,一个发送带数据音讯。最终都是在网络线程中调用PostMessage函数异步地把音讯退出到绑定的窗口句柄的音讯队列里。从而在线程运行函数里能够取出队列中的音讯。接着在CTCPSocketServiceThread::OnServiceRequest函数里进行发送音讯解决。最终调用到CTCPSocketServiceThread::SendBuffer函数,调用的是send函数进行音讯发送。2.总的来说外部网络服务会解决两种大类型的音讯,一种是被动用网络线程调用PostMessage函数投递的WM_SERVICE_REQUEST服务申请,另外一种是绑定在窗口句柄上的socket收到的WM_SOCKET_NOTIFY网络音讯。 服务申请:1.连贯申请:连贯申请会应用WSAAsyncSelect异步抉择模型,把socket绑定到窗口句柄上。并且尝试connect一个地址,如果连贯失败,网络线程会读到WM_SOCKET_NOTIFY/FD_CONNECT网络音讯/网络连接音讯。把连贯的ErrorCode发送给调度引擎。调度引擎判断是连贯谬误,就设置一个定时器,进行下一次连贯尝试。2.发送申请:用于外部网络服务发送数据。当调用send函数发送数据返回WSAEWOULDBLOCK谬误后,示意socket缓冲区已满不可写时,会调用AmortizeBuffer函数把数据缓存,这个时候,网络线程会收到WM_SOCKET_NOTIFY/FD_READ网络音讯/数据读取音讯,在CTCPSocketServiceThread::OnSocketNotifyWrite函数中再次发送数据。 网络音讯:FD_READ:1:当调用WSAAsyncSelect函数时,如果以后有数据可读。2:当数据达到并且没有发送FD_READ网络事件时。3:调用recv()或这recvfrom,如果仍有数据可读里。FD_WRITE:1:调用WSAAsyncSelect函数时,如果可能发送数据时。2:connect或者accept函数后,连贯曾经建设时。3:调用send或者sendto函数,返回WSAWOULDBLOCK谬误后,再次调用send()或者sendto函数可能胜利时。因为此时可能是套接字还处于不可写状态,屡次调用直到调用胜利为止。FD_CONNECT:当connect胜利或者失败时都会收到这个音讯,都会把错误码投递给调度引擎,如果胜利调度引擎会立刻发送一次列表音讯申请,设置定时获取列表音讯定时器。 外部网络服务是专为服务器之间外部发送接管音讯而设计的。异步抉择模型尽管接管读写告诉是异步的,然而读写数据其实还是同步的,所以性能应该比不上实现端口。 框架源码读后感长处:采纳组件模块化,从而高度复用,可扩展性强。绝大多数性能可通过读取配置或者组件配置。整个架构利用面向对象多态性,调用方保留被调用方根底接口指针,调用方间接调用接口指针内申明的纯虚办法,而此纯虚函数的具体逻辑由该接口的派生类实现。从而很好的遵循了开闭准则和依赖倒置准则等设计准则。代码正文清晰,变量,函数名,类名命名应用标准,代码可读性强。整个服务器上应用多个过程,每个过程又采纳多线程,底层采纳实现端口高性能通信模型,充分发挥cpu性能,从而保障了整个服务器的高效。应用c++,有c++编程强类型查看,高执行效率,vs编辑器弱小调试性能的长处。 可能存在的毛病大量的同步调用间接操作数据库,会影响性能,能够采纳应用redis。尽管应用了实现端口,然而可能一些应用办法,并不是实现端口举荐应用的最佳计划。但这个可能和业务需要无关,须要思考到具体应用场景。大量应用存储过程,使得对数据库的操作和存储不能拆散,开发时也不不便。较为不便的设计是数据库只负责存储数据,业务逻辑把要存储的数据处理好后用专门数据长久化服务来解决。尽管可配置性强,然而房间人数也提前配置好,这个不够正当,桌子人数能够在建房规定确定后动静初始化大厅服,房间服收发直达服数据时,应用了单线程的阻塞收发数据的TcpSocketService,这是2个服务和直达服务维持长连贯的惟一tcp连贯。有检测心跳,播送直达,音讯收发等性能。如果创立房间并发量高,这里可能也会是性能瓶颈。思考到客户端是lua,如果让服务器游戏逻辑也用lua来实现,可能会进步开发效率。同时也能够利用脚本语言的个性,实现游戏的热更新。调度引擎是解决所有其余引擎的申请的惟一消费者,然而只有一个线程,尽管调度引擎只对从队列取音讯加锁,在解决完取出的音讯前就曾经开释锁,然而像房间服务,能不能依据房间划分,把每个房间外部再加一个队列存储本房间的音讯,这样造成一个2级队列,1级队列存储的是须要解决的房间,而每个房间里又存储了这个房间的所有须要解决的音讯.而后调度引擎也用多线程并发.每次一个线程从1级队列pop一个房间,而后再从2级队列pop一条音讯,这样能够保障同一时刻只有一个线程解决一个房间的音讯.然而不同线程能解决不同房间的音讯. 本文由博客一文多发平台 OpenWrite 公布!

March 2, 2024 · 1 min · jiezi

关于后端:深入浅出Redis一对象与数据结构

引言Redis是一款基于键值对的数据结构存储系统,它的特点是基于内存操作、单线程解决命令、IO多路复用模型解决网络申请、键值对存储与简略丰盛的数据结构等等 这篇文章次要围绕Redis中的对象与数据结构来具体阐明键值对存储与简略丰盛的数据结构这两大特点 Redis中的数据以Key,Value键值对的模式存储在字典中,字典的实现是哈希表 键Key只能应用字符串对象来示意,值Value可能应用其余所有对象 对象与数据结构Redis中存在丰盛的对象,罕用的对象(数据类型)有字符串对象string、列表对象list、散列对象hash、汇合对象set、有序汇合对象zset等 还有其余的数据类型如Bitmap、Hyperloglog、Geospatial、布隆过滤器等,但这篇文章只波及罕用的对象,其余数据类型再当前的文章中再开展阐明 redis中的对象RedisObject由类型、编码、援用次数、lru、指向编码应用的数据结构对象形成 类型标识这个对象是什么类型对象 比方字符串、列表、哈希、汇合、有序汇合等编码表示形成对应类型对象时应用哪种数据结构援用次数示意这个对象被援用了多少次 redis内存回收应用援用计数法,回收援用次数为0的对象 redis只依赖字符串对象,而不存在循环依赖所以不存在循环援用,因而能够应用援用计数法lru记录这个对象最近被调用的工夫,当空间回收算法应用lru时会优先回收很久未用的对象(后续删除回收的文章会介绍)数据结构sds简略动静字符串sds应用字节数组保护,len记录字符串长度(示意结尾的'\0'不算),free示意字节数组中闲暇的长度 在增加元素前会判断数组长度是否足够,不够则会进行扩容;扩容有空间预调配策略,会留有一部分闲暇空间 如果下次批改字符串未超出数组长度就可能间接批改,节俭了扩容的开销 hashtable字典字典应用哈希表实现,哈希表的原理本篇文章不会具体概述 哈希抵触应用链地址法解决,查找时先通过 hash%数组长度-1 来获取索引,失去索引后再遍历链表节点,如果是新增则间接应用头插法,插入链表头部 为了避免大字典扩容时产生阻塞,字典中哈希表的扩容是循序渐进的,在产生扩容时会有俩个哈希表 旧哈希表和新哈希表中都可能存储数据,再收到hget等申请时先在旧哈希表中查找,找到了就顺便把它迁徙到新哈希表中;在旧哈希表中没找到就去新哈希表中找 在实现迁徙时,新哈希表将旧哈希表替换 skiplist跳表跳表保护多层级的有序链表,利用高层可能疾速达到后续节点,实现简略,保护不便,增删改查工夫复杂度均匀log n 比方查找值为2.0的节点,查找程序为图中虚线 先找到虚构头节点,从以后保护的最高层(L5)开始寻找,往后找到o3对象值为3.0,阐明曾经找过头了,于是要去下一层进行寻找;来到L4先后遍历,o1对象值为1.0,比目标值2.0小,阐明没有目标值在o1对象前面,于是来到o1对象L4层;持续在o1对象L4向后遍历,发现o3值为3.0大于目标值,于是降层来到o1对象L3层;L3层前面也是o3于是持续降层,来到L2层,L2层向后遍历为o2对象,值为2.0并比拟o2对象雷同阐明找到了 从保护的最高层开始查问,查问为空或者查问值大于目标值则降层,以后在最初一层还须要降层阐明找不到 当排序值雷同时,依照对象大小排序,这里的对象都是字符串对象 减少节点时的层数是随机生成的,越高层几率越小;其余批改操作,也是通过查问再进行,同时还要保护一些如最高层级等其余属性 intset整数汇合intset 保护了一个有序,无反复的数组 在实现上应用数组、长度(记录元素数量)和编码(编码可能标识元素类型,如16、32、64位的整型) 当退出的元素为以后数组内不存在的高位整型时(比方数组中都是32位整型,此时退出一个64位整型)产生降级:先申请内存重调配,再将旧元素挪动到对应地位上,而后退出新元素同时批改编码,当删除高位整型时不会产生降级 intset的降级无效的节约内存,当set对象都为整型且数据量较小时应用intset实现以此来节约内存 ziplist压缩列表ziplist用间断空间的节点形成,节点由记录前驱节点偏移量(逆序遍历)、编码(字节数组或整型的编码)、内容(内容能够是字节数组或整型)组成 因为ziplist的内容不是固定的,比方记录前驱节点偏移量是可变长的,这会影响节点的长度,又因为ziplist是空间间断的,这会导致后续的节点空间都要变动,被称为连锁更新(产生的概率小) 为了节俭空间,用于数量量小场景下列表、哈希、有序汇合的实现 quicklist疾速列表疾速列表能够当作双向链表,只不过节点应用ziplist,罕用来实现数据量大场景下的列表对象 对象阐明: 下文中数据量代表着占用字节状况和数据元素数量 本篇文章不介绍各个对象的命令应用规定,须要学习命令的同学能够去官网查看 字符串对象字符串对象string由sds简略动静字符串来实现 sds有不同的编码:int、embstr、row int 用来存储整型字符串,计算时可能产生整型与字符串的转换embstr 用来存储短的字符串,只调配一次内存,分配内存时同时调配redisobject和sdsrow 用来存储长字符串,分配内存时须要调配两次:redisobject、sds字符串对象是Redis中最罕用的对象,也是惟一会被其余对象依赖应用的对象 字符串对象常见的应用场景:整存整取的缓存、计数器、分布式锁 列表对象列表对象list是一个队列,能够操作队头队尾,由ziplist或quicklist来实现 数据量小时应用ziplist,数据量大时应用quicklist( linkedlist+ziplist ) 列表的应用场景是FIFO队列保障元素拜访程序 哈希对象哈希对象hash是保护KV键值对的无序数据结构,由ziplist或hashtable来实现 数据量少应用ziplist、数据量大应用hashtable 哈希的应用场景是缓存的局部存取(比方一个大礼包下有A商品B商品等) 汇合对象汇合对象set的特点是无序、无重,由intset或hashtable来实现 数据量少且数据为整型应用intset、数据量大或数据不为整型应用hashtable且值永远为null 汇合的应用场景是唯一性元素或交加并集(独特关注、可能意识)等(无序、无反复) 有序汇合对象有序汇合对象zset是有序、无重的数据结构,由ziplist或skiplist + hashtable实现 数据量少时应用ziplist、数据量大时应用skiplist + hashtable(为了满足依据对象查问分指常量级性能,共享对象,不造成内存开销) 有序汇合的应用场景是排行榜、关注水平榜单等(有序、无反复) ...

March 2, 2024 · 1 min · jiezi

关于后端:平台工程-用Backstage构建开发者门户-1

本文介绍了如何应用开源Backstage构建本人的开发者门户,并基于此实际平台工程。本系列共两篇文章,这是第一篇。原文: Platform Engineering: Building Your Developer Portal with Backstage — Part 1 在上一篇文章(平台工程与平安)中,咱们介绍了什么是平台工程,为何如此重要,和DevOps做了比拟,以及介绍了平台工程如何帮忙进步安全性。 明天咱们来入手从头开始构建一个开发者门户。 1. 当咱们议论开发者门户时,咱们在议论什么因为平台工程都是自助服务的,外部开发者门户在新范式中至关重要,在该范式中实现了所有自助服务性能和集成。 思考到开发者门户的重要性,在构建之前,须要弄清楚咱们对它的冀望到底是什么。通常,为了最大限度利用平台工程,开发者门户将蕴含一些要害性能,例如: 服务目录: 让开发人员能够鸟瞰所有我的项目、服务、部署状态、文档、所有权,甚至是值班打算和事件等;某种资源库脚手架/我的项目生成工具: 例如 Cookiecutter 这样的工具,能让开发人员从门户网站间接启动新服务;定制: 兴许你心愿将应用的任何工具链集成到开发者门户中,使其成为真正对立的一站式体验,可能的集成包含 Kubernetes、CI/CD 状态、值班打算、事件管理系统、secrets管理器等。此时,门户网站能够解决所有事务,如获取服务信息、待命打算、触发事件、部署工作以及处理事件治理。有了这些性能,开发人员就能取得真正对立的体验,在一个中央创立服务,随后跟踪和操作/保护这些服务,最大限度的施展开发者门户的后劲。 2. 抉择工具:Backstage既然晓得了开发者门户网站的真正需要,那就来构建吧。 因为它将具备多种性能,设计/编码局部自身就是一个宏大的我的项目,不是所有团队都能承当得起。因而须要一个工具来疾速构建门户网站,侥幸的是,咱们曾经有了这样的工具--Backstage。 Backstage 是用于构建开发者门户网站的开放平台。Backstage 自身并不是开发者门户,而是用于构建开发者门户的工具。想想"create-react-app"和用它创立的理论 react 利用的区别就晓得了。开箱即用的 Backstage 包含: 软件目录: 用于治理所有软件,如微服务、库、数据管道、网站和 ML 模型;软件模板: 用于疾速启动新我的项目,并依据组织的最佳实际对工具进行标准化;文档: 采纳"像编写代码一样编写文档"的办法,轻松创立、保护、查找和应用技术文档;一直倒退的开源插件生态系统,进一步扩大了 Backstage 的可定制性和性能。Backstage的架构非常灵活: 前端应用 React/TypeScript 编写,后端应用 Node.js,还能够通过增加插件来扩大性能。 更重要的是,Backstage(由 Spotify 创立)当初由云原生计算基金会(CNCF)作为孵化级我的项目托管,这意味着咱们能够取得想要的所有社区反对。它还设有办公时间,能够在每周四加入互动,精确理解开源平台如何进步开发人员的效率和体验。 说得够多了。明天咱们将从头开始,本人构建一个开发者门户。实现本教程后,能够应用带有内置平安 CI 工作流的模板来疏导一个新服务,查看 CI 状态,并在同一个中央查看该服务的文档。 废话少说,开始吧。 3. 构建门户网站3.1. 前提条件不多,可能所有 DevOps 工程师都曾经具备: 基于 Unix 的操作系统。例如,能够在 macOS、Linux 或 Windows Subsystem for Linux (WSL) 上运行。curl、git、DockerNode.js, yarn3.2. 创立门户网站运行: ...

March 2, 2024 · 3 min · jiezi

关于后端:深入浅出Redis零Redis常用命令的使用

前言Redis是一款基于键值对的数据结构存储系统,它的特点是基于内存操作、单线程解决命令、IO多路复用模型解决网络申请、键值对存储与简略丰盛的数据结构等等 本篇文章作为深入浅出Redis(一):对象与数据结构的根底篇,将深入浅出的介绍Redis中常用命令,如果想理解底层实现能够去观看那篇文章 Redis中的命令分为两种,一种则是所有对象通用的,另一种是专门为对象应用的 本篇文章将先简略阐明通用命令,再阐明五大对象(string、hash、list、set、zset)专用命令 通用命令keys *查看所有keysort key 对key进行排序,key只能是list、set、zset对象exists key查看这个key是否存在,存在为1,不存在为0  127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379> exists name (integer) 1 127.0.0.1:6379> exists names (integer) 0move key db把这个key挪动到编号为几的数据库,胜利为1,失败为0  127.0.0.1:6379> move name 3       (integer) 1 127.0.0.1:6379> keys  * 1) "age" 127.0.0.1:6379> select 3 OK 127.0.0.1:6379[3]> keys * 1) "name"把name挪动到了编号为3的数据库(第四个数据库) expire key seconds让这个key多少秒生效,返回1为胜利,0为失败ttl key查看这个key的无效工夫,返回-1为永恒,-2为已过期,其余数字代表无效秒数  127.0.0.1:6379[3]> expire name 10 (integer) 1 127.0.0.1:6379[3]> ttl name (integer) 7 127.0.0.1:6379[3]> ttl name (integer) 6 127.0.0.1:6379[3]> ttl name (integer) 5 127.0.0.1:6379[3]> ttl name (integer) 4 127.0.0.1:6379[3]> ttl name (integer) 2 127.0.0.1:6379[3]> ttl name (integer) -2 127.0.0.1:6379[3]> ttl name (integer) -2 127.0.0.1:6379[3]> ttl name (integer) -2 127.0.0.1:6379[3]> expire name 10 (integer) 0 127.0.0.1:6379[3]> keys * (empty list or set)type key返回这个key的类型 ...

March 2, 2024 · 5 min · jiezi

关于后端:Git-分支管理优化版本控制与应急处理的关键策略

应用 Git 分支:轻松治理不同版本和应答紧急情况的最佳实际应用 Git 分支在 Git 中,分支是主仓库的新/独立版本。 假如你有一个大型项目,须要对其进行设计更新。 没有应用 Git 时: 复制所有相干文件以防止影响实时版本开始进行设计工作,并发现代码依赖于其余文件中的代码,这些文件也须要更改!复制相干文件,确保每个文件依赖项援用正确的文件名紧急情况!我的项目的其余中央存在无关的谬误,须要尽快修复!保留所有文件,记录你正在工作的正本的名称解决无关的谬误并更新代码以修复它返回到设计工作,实现工作复制代码或重命名文件,以使更新后的设计呈现在实时版本中(两周后,你意识到未修复无关的谬误,因为在修复之前你复制了文件) 应用 Git 时: 应用名为 "new-design" 的新分支,间接编辑代码,而不影响主分支紧急情况!我的项目的其余中央存在无关的谬误,须要尽快修复!从主我的项目创立名为 "small-error-fix" 的新分支修复无关的谬误并将 "small-error-fix" 分支与主分支合并返回到 "new-design" 分支,实现工作合并 "new-design" 分支与主分支(揭示你正在短少的小谬误修复)分支容许你在我的项目的不同局部上工作,而不影响主分支。 当工作实现后,能够将分支与主我的项目合并。 你甚至能够在不同分支之间切换,同时在不同我的项目上工作,而彼此不会相互烦扰。 在 Git 中,分支十分轻量且疾速! 创立新 Git 分支让咱们向咱们的 index.html 页面增加一些新性能。 咱们在本地仓库中工作,不心愿烦扰或可能毁坏主我的项目。 所以咱们创立一个新分支: git branch hello-world-images 当初咱们创立了一个名为 "hello-world-images" 的新分支。 让咱们确认咱们曾经创立了一个新分支: git branch hello-world-images* master咱们能够看到新分支的名称为 "hello-world-images",但在 master 旁边的 * 指定咱们以后在该分支上。 checkout 是用于检出分支的命令,将咱们从以后分支挪动到命令开端指定的分支: git checkout hello-world-images当初咱们已将当前工作区从 master 分支挪动到新分支。 关上你最喜爱的编辑器并进行一些更改。 在此示例中,咱们在工作目录中增加了一个图像(img\_hello\_world.jpg)和 index.html 文件的一行代码: <!DOCTYPE html><html><head><title>Hello World!</title><link rel="stylesheet" href="bluestyle.css"></head><body><h1>Hello world!</h1><div><img src="img_hello_world.jpg" alt="Hello World from Space"style="width:100%;max-width:960px"></div><p>This is the first file in my new Git Repo.</p><p>A new line in our file!</p></body></html>咱们对一个文件进行了更改,并在工作目录中增加了一个新文件(与主分支雷同的目录)。 ...

March 1, 2024 · 1 min · jiezi

关于后端:上云还是下云最大挑战是什么-对话章文嵩毕玄王小瑞

近半年来,私有云畛域频频产生阿里云、滴滴等平台解体事件,与此同时,马斯克的“X 下云省钱”舆论引起了宽泛关注,一时间,“上云”和“下云”成为热议话题。在最近举办的 AutoMQ 云原生翻新论坛上,AutoMQ 联结创始人兼 CEO 王小瑞作为圆桌主持人,与 AutoMQ 联结创始人兼 CSO 章文嵩、贝联珠贯创始人兼 CEO 林昊(毕玄)两位技术大咖,围绕上云与下云的趋势之争,以及面临的挑战开展思维碰撞。  Q1:云厂商的营收一路飙升,但同时又听到各种下云的案例,比方推特下云节俭了 60\% 的老本,将来趋势是什么?章文嵩:我感觉上云必定是大势所趋。因为云是给客户发明价值的,就云计算的实质来说是资源的聚合与复用,通过超卖的形式实现老本的升高,从而帮忙客户实现老本节俭,同时也为云厂商发明盈利机会。以一个简略的例子来阐明,本来 A 用户和 B 用户别离在白天和早晨应用机器,每个时段都须要破费一个单位的老本。然而,云厂商的呈现让 A 和 B 都不再须要购买机器,而是通过租赁的形式,付给云厂商较低的费用如 0.6,使得云厂商的支出 1.2 超过了 1 个单位的老本,实现了盈利,客户也省钱了。通过错峰应用,A 用户和 B 用户依然可能没有消耗掉全副的计算资源,云厂商有机会还能将未应用的资源卖给其余用户,实现了资源的高效复用。另外还有研发资源的复用,随着零碎规模的增大,边际老本升高,云计算成为一个可能继续发明价值的解决方案。比方美国的一份报告阐明,在所有的 IT 收入外面,2022 年美国云计算的渗透率将近 10\%,而 Gartner 预测到 2026 年,这一比例将回升至 20\%。在中国,只管 SaaS 行业倒退尚未成熟,但 IaaS 和 PaaS 模式曾经在云厂商中失去广泛应用。以阿里云为例,过来两年始终放弃盈利,阿里云所有云资源的支出加在一块,大略是一年 1000 亿左右,阿里云市场份额占比 30\%-40\%,整个中国云市场的规模约为 3000 亿。通过工信部颁布的中国整体 IT 行业的支出 10 万亿,能够得悉中国云市场渗透率大略 3\% 。当然中国将来 SaaS 空间会很大,所以美国如果四五年后达到 20\% 的云渗透率,那中国有可能到 10\% 以上的渗透率,将来 50\% 甚至 70\% 以上的渗透率,所以我感觉上云是大势所趋。 毕玄:守业后,我接触到了更实在的状况。以前代表阿里云访问客户时,客户因我可能促使他们购买更多阿里云产品而防止说实话。当初作为中立方,客户更违心分享实在想法。从整体趋势上来看,我深信云计算有微小增长空间。只管中国云市场增速降落,甚至阿里云是比前两年有下滑,但这有很多综合起因,总体上我感觉云必定还会持续增长。许多公司掂量云老本的办法很简略,即比拟线下机器收入和搬到云上的费用。但思考到人工成本,难以简略比照。大公司即便迁徙到云上,人工成本依然存在,因基础设施管理人员短期内难裁员。我之前跟某互联网头部公司的人聊到底是要往云上搬,还是持续放弃自建的话题,外围还是要搬到云上,充分发挥云的弹性,而不是动态应用。纯动态用对大公司来讲老本难以均衡。弹性应用云,尤其是按量计费,就像当初中国按量计费比包年包月其实单价贵很多。在折扣会谈中,按量付费和包年包月离开谈,通常包年包月计划能取得更低的折扣,因为按量支出不确定性较大。另外一个问题是中国的按量错峰效应不够显著,云厂商对此不太热衷。只管按量计费可能减少老本,但之前通过推演,咱们发现在折扣会谈后,每天应用 8 小时左右可能实现老本打平。一些大公司进行了假如推演,从线下切换到按量计费和齐全弹性零碎,能显著节省成本。然而,因为技术改造较多,很多公司不愿采纳这种形式,但我认为这是技术的趋势,很多公司肯定会越来越弹性。对于大部分中小企业而言,云计算的灵活性比老本更为重要,因而它们更天然地采纳云服务。从老本角度来看,随着技术的演进,整体用云的老本将逐步升高,比自建更具劣势。同时,云计算的利用一直减少也是因为壁垒的存在。在 AI 时代,大多数企业首选应用云而不是自建,因为自建的门槛较高,而云服务为业务疾速翻新提供了重要反对。 ...

March 1, 2024 · 2 min · jiezi

关于后端:maven-包管理平台-windows-安装配置-mac-安装配置

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 MavenApache maven 是一个软件项目管理和了解工具。 基于我的项目对象模型(POM)的概念,Maven 能够从一个核心信息管理我的项目的构建、报告和文档。 Maven权威指南zh_CN.pdfwindows 装置要求:JDK: Maven 3.3 须要 JDK 1.7 或更高版本能力执行 - 它依然容许您针对 1.3 和其余 JDK 版本进行构建,应用 Toolchains磁盘空间: Maven 装置自身须要大概 10MB。除此之外,您的本地 Maven 仓库还将应用额定的磁盘空间。您的本地仓库大小将依据应用状况而变动,但至多须要 500MB。 装置 文档中文版 下载下载配置环境变量MAVEN_HOME: D:\Maven\apache-maven-3.3.9门路%MAVEN_HOME%/bin;验证测试:mvn -v后果Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)Maven home: D:\Maven\apache-maven-3.3.9\bin\..Java version: 1.7.0_79, vendor: Oracle CorporationJava home: D:\Program Files\Java\jdk1.7.0_79\jreDefault locale: zh_CN, platform encoding: GBKOS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"mac 装置下载下载 Maven apache-maven-3.3.9-bin.tar.gz,解压并将文件重命名为 maven3.3.9。在 mac 终端中,输出以下命令:$ pwd获取以后门路。而后输出以下命令: ...

March 1, 2024 · 1 min · jiezi

关于后端:MavenGradleAntIvyBazel-和-SBT-的详细对比

拓展浏览maven 包治理平台-01-maven 入门介绍 + Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的具体比照表格 maven 包治理平台-02-windows 装置配置 + mac 装置配置 maven 包治理平台-03-maven project maven 我的项目的创立入门 maven 包治理平台-04-maven archetype 我的项目原型 maven 包治理平台-05-multi module 多模块 maven 包治理平台-06-罕用技巧 实时更新快照/乱码问题/下载很慢/包依赖解决包抵触/如何导入本地 jar maven 包治理平台-07-plugins 常见插件介绍 maven 包治理平台-08-nexus 本人搭建 maven 仓库 MavenApache maven 是一个软件项目管理和了解工具。 基于我的项目对象模型(POM)的概念,Maven 能够从一个核心信息管理我的项目的构建、报告和文档。 chat具体介绍一下 mavenMaven 是一个风行的项目管理工具,次要用于 Java 我的项目的构建、依赖治理和项目管理。 它提供了一种标准化的形式来构建我的项目,使得我的项目构建过程更加自动化、简化和可保护。 以下是对于 Maven 的具体介绍: 1. 我的项目构建Maven 提供了一种称为 POM(Project Object Model)的我的项目对象模型,它是一个 XML 文件,形容了我的项目的根本信息、依赖关系、插件配置等。通过定义 POM,Maven 可能执行我的项目的构建和治理。 2. 依赖治理Maven 提供了弱小的依赖治理性能。通过在 POM 中申明我的项目所需的依赖,Maven 可能主动下载这些依赖,并且能够治理依赖的版本和传递性依赖。这简化了我的项目的配置和构建过程,也确保了我的项目的依赖关系的一致性。 ...

March 1, 2024 · 2 min · jiezi

关于后端:轻松管理基于-RAG-的知识库RBAC-的最佳实践来了

随着大型模型技术的日益成熟,越来越多企业踊跃尝试在外部利用这一前沿技术,上线各类翻新的 AI 利用,这标记着科技领域的一大飞跃。在这个发展趋势中,向量数据库凭借其弱小的数据反对,成为 RAG(Retrieval-Augmented Generation)、智能体等 AI 利用的关键技术。 然而,随着企业应用和数据的一直蓬勃增长以及多样化倒退,对于数据拜访的安全性需要也逐步升高。如何隔离不同我的项目、不同用户之间的数据和资源,使团队合作更加高效,成为许多企业面临的一项重要挑战。在这篇文章中,咱们将摸索 Zilliz Cloud 基于角色的访问控制及不同场景下的最佳实际。 01.理解 Zilliz Cloud RBACZilliz Cloud 的 RBAC(角色权限访问控制)性能提供了一种结构化和可扩大的办法来治理数据拜访权限,保障数据安全。RBAC 通过以下层面实现访问控制:用户账户、组织、我的项目。 其中,组织是将领有独特指标的多个我的项目汇聚在一起,例如,将某个特定业务单元下的所有我的项目整合在同一组织中。 在一个组织下,用户能够创立若干我的项目,并治理组织级别的资源,包含账单、组织成员、事件、零碎设置以及回收站等。 我的项目是组织外部用于归类集群和其余相干资源的逻辑分组单位。在一个我的项目中,你能够创立若干集群,并治理集群级别的资源,包含我的项目成员、API 密钥、平安设置和监控等。 02.Zilliz Cloud RBAC 是如何工作的?Zilliz Cloud 权限设计遵循 RBAC 准则,分为管控层和数据层 2 层角色。在管控层,角色主持集群、我的项目、用户和账单等资源的操作权限,而在数据层,角色则专一于管制对 Cluster 数据的增、删、改、查的能力。 在管控层,Zilliz Cloud 反对 4 种角色(组织管理员、我的项目所有者和我的项目成员是 3 种罕用的角色): 组织管理员:领有对组织的全副管理权限,包含组织设置、治理领取形式及账单、API Key、组织中的所有我的项目以及相干资源。组织成员:在组织中具备无限的拜访权限,能够查看组织设置并邀请用户退出组织。组织成员对组织层面、我的项目层面和集群层面的资源的具体权限范畴由其在我的项目中的角色确定。我的项目所有者:领有对我的项目的全副管理权限,包含我的项目设置、我的项目内的 API Key、我的项目内的所有集群以及相干资源。我的项目成员: 对我的项目内的所有集群具备读写权限,能够查看集群详情并治理 Collection和 Index。在数据层,Zilliz Cloud 提供了 3 种内建角色:Admin、Read-Only 和 Read-Write,用于管制对 Cluster 数据的读写和管理权限: Admin(管理员):领有 Cluster 的最高权限,能够执行所有操作。Read-write(读写):具备对 Cluster 数据进行读写的权限,实用于须要批改数据的场景。Read-only(只读):具备对 Cluster 下所有数据进行只读拜访的权限,实用于只须要查看数据而不批改的场景。然而,思考到特定业务需要,例如,只容许受权人员拜访敏感数据或者心愿应用 Collection 作为多租户隔离单元以确保安全隔离数据拜访,Zilliz Cloud 容许用户创立自定义角色。这些自定义角色可能定义对特定 Collection、Partition 或操作的权限,确保在应用 Zilliz Cloud 时实现数据权限最小化准则。 ...

March 1, 2024 · 1 min · jiezi

关于后端:平台工程与安全

平台工程不是为了取代DevOps,而是DevOps的进一步演进和倒退。本文介绍了DevOps和平台工程,以及对于平安的意义。原文: Platform Engineering and Security: A Very Short Introduction 我是一名 DevOps 工程师,集体还是心愿 DevOps 依然有其意义,因为很显然,如今已是"DevOps 已死,平台工程万岁"的时代了。 不可否认,自 2022 年以来,咱们更频繁的看到"平台工程(platform engineering)"、"开发者门户(developer portal)"以及"后盾(Backstage)"等术语。 本文将答复几个根本问题:DevOps 真的死了吗?什么是平台工程?区别是什么?平台工程如何解决 DevSecOps/平安问题? DevOps 已死?简略来说,并没有。 如果我这么多年来在技术畛域学到了什么,那就是技术、框架和方法论从未真正沦亡,而是会成长、适应和倒退。 例如,想想麻利开发。你第一次据说麻利开发是什么时候?当初死了吗?这就是问题所在。 但某种程度上,DevOps 的确"死"了。尽管从传统意义上讲,DevOps 并没有从科技界隐没,但的确"死"了,因为许多尝试 DevOps 的公司和团队都没有达到预期。 不过这并不是什么新闻,因为早在多年前,技术钻研和征询公司 Gartner 的一位数据分析师就曾经预测,在整个 2022 年,75% 的 DevOps 打算将无奈达到预期指标,而到 2023 年,这一数字可能会增长到 90%。 但须要指出的是,这些 DevOps 打算的失败并不是因为技术上的挑战,而是因为信赖、所有权和团队单干等被忽视的人为因素。 DevOps 本应是解决传统经营孤岛中所有问题的银弹,让所有从新变得美妙。然而可怜的是,许多团队并没有达到最后预期,而且开发人员仿佛并不想从事运维工作: 开发人员不想从事运维?偏心的说,这取决于你问的是谁。有些开发人员认为 DevOps "谁构建,谁运维"的模式必定是无益的,甚至有时是必要的,而有些开发人员则基本不想接触运维。 Twitter 上有一项对于此问题的民意调查,330 名开发人员参加了考察,考察结果显示,41.8% 的受访者示意反对运维工作,42.1% 的受访者示意不反对,16.1% 的受访者示意无所谓。 因而,开发人员更违心防止与基础架构和运维打交道,这对 DevOps 来说是个坏兆头。在这种状况下,平台工程变得前所未有的热门。 平台工程现在,非专业的最终用户常常被要求运维一系列简单的服务,这简直是不可能的。平台工程与 DevOps 一样,都是为应答日益简单的古代软件架构而呈现的。 DevOps 试图从文化角度解决软件开发生命周期(SDLC)中的合作和速度问题,即器重责任分担模式、继续成长和学习心态,激励团队单干、最佳实际和古代工具链,而平台工程则试图从另一个角度来解决问题:自助服务。 咱们来看一个具体例子: 团队中的开发人员须要为新创建的利用创立数据库,但他们可能并不齐全理解如何应用正确的自动化工具(比方Terraform)在特定云服务商(比方AWS)中创立关系数据库(RDS),并非所有开发人员都晓得基础架构在哪里运行以及如何协调。 解决这个问题的 DevOps 办法是使团队具备足够的跨职能常识,让团队中的某个人把握 AWS 服务和基础设施即代码的专业知识,更重要的是领有适当权限,通过编写 Terraform 模块和在 AWS 中部署 RDS 来自动化配置云资源。 ...

March 1, 2024 · 1 min · jiezi

关于后端:从前端JS逆向到发现后端越权漏洞的渗透测试之旅

前言本篇文章首发先知社区,作者为本公众号。 前端剖析首先搜寻申请接口,未发现要害加密点 依据申请参数进行搜寻 在js文件中找到aes加密key、iv eval(function(p, a, c, k, e, r) { e = function(c) { return c.toString(36) } ; if ('0'.replace(0, e) == 0) { while (c--) r[e(c)] = k[c]; k = [function(e) { return r[e] || e } ]; e = function() { return '[0-9a-x]' } ; c = 1 } ;while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b','g'), k[c]); return p}('(3($){e();2 j=$.f;$.f=3(1){5(1.0!=\'\'&&1.0!=g){2 h=9 k();2 a=9 k();5(1.contentType=="application/json"){a=1.0}l{for(2 m in 1.0){2 4=m;5(1.0[4]!=g&&1.0[4].length>460){a[4]=1.0[4]}l{h[4]=1.0[4]}}}1.0=a;1.0.keyScript=n(o(JSON.stringify(h)))}2 p=$.extend(1,{beforeSend:3(jqXHR,settings){}});i j(p)}})(jQuery);3 e(){5(6.7==g||6.7==null||6.7==\'\'){$.f({type:\'GET\',async:false,url:Globals.ctx+"/e/generate",0:{nowDate:9 Date()},q:3(0){5(0.q){6.7=0.body}}})}}3 o(b){2 c=9 JSEncrypt();c.setPublicKey(6.7);2 d=c.encryptLong(b);i d.r()}3 n(b){2 s=8.t.u.v("xxxxx");2 w=8.t.u.v(b);2 d=8.AES.c(w,s,{x:8.x.ECB,padding:8.pad.Pkcs7});i d.r()}', [], 34, 'data|opt|var|function|arrayName|if|window|publicKey|CryptoJS|new|noEncrypt|message|encrypt|encrypted|dynamicKey|ajax|undefined|isEncrypt|return|_ajax|Object|else|index|AesEncrypt|RsaEncrypt|_opt|success|toString|key|enc|Utf8|parse|srcs|mode'.split('|'), 0, {}))持续跟进,发现了两个加密函数:RsaEncrypt、AesEncrypt ...

March 1, 2024 · 3 min · jiezi

关于后端:容易发生内存泄漏的八个场景你都知道吗

内存透露与内存溢出JVM在运行时会存在大量的对象,一部分对象是短暂应用的,一部分对象只会短暂应用 JVM会通过可达性剖析算法和一些条件判断对象是否再应用,当对象不再应用时,通过GC将这些对象进行回收,防止资源被用尽 内存透露:当不再须要应用的对象,因为不正确应用时,可能导致GC无奈回收这些对象 当不正确的应用导致对象生命周期变成也是宽泛意义上的内存透露 内存溢出:当大量内存透露时,可能没有资源为新对象调配 举例内存透露接下来将从对象生命周期变长、不敞开资源、扭转对象哈希值、缓存等多个场景举例内存透露 对象生命周期变长引发内存透露动态汇合类public class StaticClass { private static final List<Object> list = new ArrayList<>(); /** * 只管这个局部变量Object生命周期十分短 * 然而它被生命周期十分长的动态列表援用 * 所以不会被GC回收 产生内存溢出 */ public void addObject(){ Object o = new Object(); list.add(o); }}类卸载的条件十分刻薄,这个动态列表生命周期根本与JVM一样长 动态汇合援用部分对象,使得部分对象生命周期变长,产生内存透露 饿汉式单例模式public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton(){ if (INSTANCE!=null){ throw new RuntimeException("not create instance"); } } public static Singleton getInstance(){ return INSTANCE; }}饿汉式的单例模式也是被动态变量援用,即时不须要应用这个单例对象,GC也不会回收 非动态外部类非动态外部类会有一个指针指向外部类 ...

March 1, 2024 · 2 min · jiezi

关于后端:DNS服务器管理与配置技巧

人们或者都有这样一个困惑:计算机在网络上通信时原本只能辨认如“123.123.123.123”之类的数字地址,那么为什么当咱们关上浏览器,在地址栏中输出域名www.dexunyun.com后,就能看到咱们所须要的页面呢? 其实,只是一个IP地址和域名互相“翻译”的过程。前者得建设一个指向相应IP地址的域名映射记录;对于后者,此记录曾经建设并且在失效了。而这种“翻译”记录的建设,则须要用到同一种被称之为“DNS服务器”的计算机。 DNS服务器用于TCP/IP网络中,它用来通过用户敌对的名称代替难记的IP地址以定位计算机和服务。因而,只有你须要用到某个域名的中央,你都得首先确保已为此名字在DNS服务器中作好了相应的和IP地址的映射工作。 本文将以Windows2003自带的DNS服务为例,谈下如何在局域网中实现这个“翻译零碎”的组建工作。 一、增加DNS服务 当你装置好Win2003之后,DNS服务并没有被增加进去。顺次关上“开始→控制面板→增加/删除程序→增加/删除Windows组件,单击增加或删除Windows组件。在组件列表中,单击网络服务(但不要选中或革除该复选框),而后单击详细信息。单击已选中域名零碎(DNS),而后单击确定。 单击下一步,失去提醒后,将WindowsServer2003CD-ROM插入计算机的驱动器。装置实现时,在实现Windows组件向导页上单击实现。 二、配置DNS服务器 要应用Microsoft治理控制台(MMC)中的DNS治理单元配置DNS,请依照下列步骤操作:单击开始,指向程序,指向管理工具,而后单击DNS。右击正向搜寻区域,而后单击新建区域。当“新建区域向导”启动后,单击下一步。接着将提醒您抉择区域类型。 区域类型包含: 次要区域:创立能够间接在此服务器上更新的区域的正本。此区域信息存储在一个.dns文本文件中。 辅助区域:规范辅助区域从它的主DNS服务器复制所有信息。主DNS服务器能够是为区域复制而配置的Active Directory区域、次要区域或辅助区域。辅助DNS服务器上的区域数据无奈批改。所有数据都是从主DNS服务器复制而来。 存根区域:存根区域只蕴含标识该区域的权威DNS服务器所需的资源记录。这些资源记录包含名称服务器(NS)、起始受权机构(SOA)和可能的glue主机(A)记录。 Active Directory中还有一个用来存储区域的选项。此选项仅在DNS服务器是域控制器时可用。 新的正向搜寻区域必须是次要区域或Active Directory集成的区域,以便它可能承受动静更新。单击次要,而后单击下一步。 新区域蕴含该基于Active Directory的域的定位器记录。区域名称必须与基于Active Directory的域的名称雷同,或者是该名称的逻辑DNS容器。例如,如果基于Active Directory的域的名称为“www.dexunyun.com”,那么无效的区域名称只能是“www.dexunyun.com”,承受新区域文件的默认名称。 如何移除根DNS区域 运行WindowsServer2003的DNS服务器在它的名称解析过程中遵循特定的步骤。首先查问它的高速缓存,而后查看它的区域记录,接下来将申请发送到转发器,最初应用根服务器尝试解析。 默认状况下,Microsoft DNS服务器连贯到Internet以便用根提醒进一步解决DNS申请。当应用Dcpromo工具将服务器晋升为域控制器时,域控制器须要DNS。如果在晋升过程中装置DNS,会创立一个根区域。这个根区域向您的DNS服务器表明它是一个根Internet服务器。因而,您的DNS服务器在名称解析过程中并不应用转发器或根提醒。 这时能够抉择将根DNS区域移除。单击开始,指向管理工具,而后单击DNS。开展Server Name,其中Serve Name是服务器的名称,单击属性,而后开展正向搜寻区域。右击“。”区域,而后单击删除即可。 如何配置转发器 WindowsServer2003能够充分利用DNS转发器。该性能将DNS申请转发到内部服务器。如果DNS服务器无奈在其区域中找到资源记录,能够将申请发送给另一台DNS服务器,以进一步尝试解析。一种常见状况是配置到您的ISP的DNS服务器的转发器。 单击开始,指向管理工具,而后单击DNS。右击Server Name,其中Server Name是服务器的名称,而后单击转发器选项卡。单击DNS域列表中的一个DNS域。或者单击新建,在DNS域框中键入心愿转发查问的DNS域的名称,而后单击确定。 在所选域的转发器IP地址框中,键入心愿转发到的第一个DNS服务器的IP地址,而后单击增加。。 DNS是Internet上应用的外围名称解析工具,负责主机名称和Internet地址之间的解析。进行必要的正当的设置,会使咱们的工作达到事倍功半的成果。

March 1, 2024 · 1 min · jiezi

关于后端:面试官说说SSO单点登录的实现原理

单点登录(Single Sign-On, SSO)是一种让用户在多个利用零碎之间只需登录一次就能够拜访所有受权零碎的机制。单点登录次要目标是为了进步用户体验并简化平安治理。 举个例子,您在一个大型企业工作,该企业领有一套由多个独立应用程序组成的生态系统,例如:外部邮箱零碎、我的项目管理系统、员工自助服务零碎、人力资源信息系统等。 而这些零碎在没有施行单点登录的状况下会呈现以下问题: 用户体验方面: 每天开始工作时,员工须要别离登录每一个零碎能力失常发展工作,这不仅耗时,而且容易造成明码疲劳,即频繁记忆和输出不同零碎的登录凭证,升高了工作效率。举例:员工小王每天下班要先登录外部邮箱查看重要告诉,而后切换至我的项目管理系统更新进度,接着进入人力资源信息系统查看工资单。如果没有 SSO,他须要在每个零碎独自输出用户名和明码。平安治理方面: 各个系统间的明码策略可能不统一,员工可能会因为难以记忆而在多个零碎应用同一明码,减少了数据泄露的危险。同时,管理员对用户账户的治理、权限变更及审计也会变得复杂。举例:若小王在每个零碎应用雷同明码,一旦某一零碎存在安全隐患导致明码泄露,攻击者就有可能借此尝试登录其余零碎。而有了 SSO,管理员只需在一处更改或撤销小王的登录权限,就能影响所有相干零碎。采纳单点登录后,小王只需在一天开始时登录一次,之后拜访其余所有零碎时都将自动识别其身份并受权拜访,无需再次验证。这样既缩小了用户登录累赘,又进步了安全性,因为管理员能够通过对立的入口更无效地执行身份验证、受权以及审计策略。同时,SSO 还能够配合多因素认证(MFA)等加强措施,进一步晋升整个零碎的安全级别。 1.单点登录实现原理单点登录是在用户登录一个业务零碎时,先将登录信息发送至独自的 SSO 服务器进行认证,如果认证胜利则向该应用程序或零碎发送受权令牌,之后该用户就能够应用受权令牌实现登录并操作所有零碎了。 独自登录通常的操作流程是这样的: 用户认证: 用户首先拜访一个零碎,输出用户名和明码进行登录。登录申请被发送到专门的认证核心(Authentication Server)。认证核心验证用户的身份信息,如果验证胜利,则生成一个平安令牌(如 JWT、Ticket 等)。令牌发放与传递: 认证核心将令牌返回给用户首次登录的利用零碎。利用零碎将令牌存储在用户的本地会话(如浏览器的 Cookie)中。当用户拜访其余须要 SSO 反对的利用零碎时,浏览器会携带令牌主动发送给指标零碎。令牌验证与受权: 指标零碎接管到申请后,发现携带了令牌,则将令牌发送给认证核心进行验证。认证核心验证令牌的有效性(包含签名、有效期等)。如果令牌无效,认证核心会返回一个确认信息给指标零碎,证实用户已通过认证。资源共享与受权: 指标零碎接管到认证核心的确认后,容许用户拜访系统资源,而无需再次登录。指标零碎能够根据令牌中的信息进行权限管制和角色映射。会话治理: 为了保障安全性,个别会设置令牌的有效期,过了有效期后须要从新认证。在某些实现中,当用户在一个子系统中登记时,会告诉认证核心撤销所有关联令牌,从而实现全局登记,保障了其余零碎也无奈持续应用过期的认证信息。在技术实现上,单点登录能够借助如 CAS(Central Authentication Service)、OAuth、OpenID Connect 等标准协议,也能够基于企业外部的自定义协定实现。在整个流程中,要害是要保护一个全局认可的信赖票证(token),并通过集中式的认证服务中心来进行身份的对立治理和验证。 2.单点登录实现在 Java 我的项目中,实现单点登录(SSO)的计划次要有以下几种: OAuth2 + JWT(JSON Web Tokens)计划:OAuth2 是一个凋谢规范,容许用户受权第三方利用拜访他们在服务提供商处存储的特定信息,而不须要将用户名和明码提供给第三方利用。JWT 是一种用于身份验证和受权的令牌,通常与 OAuth2 一起应用。在 Spring Boot 中,你能够应用 Spring Security OAuth2 和 JWT 库来实现这种计划。CAS(Central Authentication Service)单点登录计划:CAS 是一个开源的、用于企业级的单点登录解决方案。它提供了一套服务端和客户端的组件,使得在多个利用之间实现单点登录变得简略。在 Spring Boot 中,你能够应用 Spring Security CAS 客户端来实现这种计划。Spring Security + OAuth2:Spring Security 是一个提供身份验证和受权性能的框架,它能够与 OAuth2 一起应用来实现单点登录。在这种计划中,你能够应用 Spring Security 来解决用户的身份验证和受权,而后应用 OAuth2 来治理用户在多个利用之间的拜访。Spring Session:Spring Session 是一个用于治理用户会话的框架,它能够帮忙你在多个利用之间共享会话信息,从而实现单点登录。你能够应用 Spring Session 来将会话信息存储在共享的中央(如 Redis),而后在每个利用中通过 Spring Session 来拜访这些会话信息。其中,OAuth2 + JWT 计划适宜于须要对外提供 API 接口的利用,而 CAS 计划则更适宜于外部零碎之间的单点登录。Spring Security + OAuth2 计划则是一种比拟通用的抉择,既能够解决外部零碎的单点登录,也能够解决对外提供 API 接口的状况。Spring Session 计划则更适宜于须要将会话信息共享到多个利用之间的场景,它也是最早和最简略的单点登录实现形式。 ...

March 1, 2024 · 1 min · jiezi

关于后端:JVM参数太多一网打尽常用JVM参数

JVM提供的参数十分多,并且各种类型的参数可能提供不同的性能 了解JVM运行原理和相熟罕用JVM参数可能帮忙咱们更好的进行调优 本篇文章将介绍JVM参数的分类,以及GC日志、运行时内存区、OOM、垃圾收集器相干的罕用参数 罕用JVM参数JVM参数能够分为三种类型,别离是以-、-X、-XX结尾的参数 -结尾的参数比较稳定,后续版本根本不变,如-version 查看版本信息 -X结尾的参数比较稳定,后续版本可能扭转,如-Xmx设置初始堆内存大小 -XX结尾的参数不稳固,后续版本会变动,如-XX:MetaspaceSize 设置元空间大小 GC日志相干通过GC日志可能剖析JVM产生GC时各个数据区的状况 -XX:+PrintGC 或 -verbose:gc 输入简略GC日志信息 -XX:+PrintGCDeatils 输入具体GC日志信息 -XX:+PrintGCTimeStamps 和 -XX:+PrintGCDateStamps 则是在具体输入GC日志信息的根底上减少工夫,前者输入程序运行工夫,后者输入工夫戳 其余参数还有 -Xloggc:d:\gc.log 将GC信息输入到d:\gc.log文件;-XX:PrintHeapAtGC 每次GC前后打印堆信息等 运行时数据区相干JVM有对各种运行时数据区(栈、堆、办法区、间接内存)的参数,常应用-XX命令,有些命令也可用-X来代替 栈-XX:ThreadStackSize=100k 设置栈内存大小100k,能够应用 -Xss100k代替 栈是线程公有的,设置太大且创立线程多的场景下,可能会内存不足导致OOM 堆-XX:InitalHeapSize=100m 设置堆内存初始化为100m,能够应用 -Xms100m代替 -XX:MaxHeapSize=100m 设置最大堆内存为100m,能够应用 -Xmx100m代替 当-Xms和-Xmx设置成一样的值时,JVM就不须要对堆内存扩容,可能优化一些性能,但占用内存少时可能造成节约 当咱们的开发工具idea比拟卡时,能够用这两个参数将idea堆内存进行调整(idea 也是Java过程) -Xmn2g 设置年老代最大内存为2g,等同于-XX:NewSize=2g+-XX:MaxNewSize=2g -XX:+UseAdaptiveSizePolicy 主动抉择各区比例大小(默认开启) -XX:SurvivorRatio=8 设置survivor:Eden占比为 1:1:8(如果-XX:+UseAdaptiveSizePolicy是开启的,survivor:eden比例会被主动调成为1:1:6) -XX:NewRatio=2 设置年老代:老年代占比为 1:2 察看GC日志,如果是因为年老代空间不够导致频繁minor GC,能够适当调整年老代与老年代比例 -XX:PretenureSizeThreadshold=2014 设置内存大于此值(byte)的对象作为大对象间接调配到老年代 -XX:MaxTenuringThreshold=15 对象年龄超过15进入老年代 -XX:+PrintTenuringDistribution JVM每次MinorGC后打印出以后应用的Survivor中对象的年龄散布 -XX:TargetSurvivorRatio MinorGC完结后Survivor区域中占用空间的冀望比例 办法区-XX:MetaspaceSize 元空间初始大小 -XX:MaxMetasoaceSize 元空间最大大小 -XX:+UseCompressedOops 应用压缩对象指针 -XX:+UseCompressedClassPointers 应用压缩类执行 -XX:ComporessedClassSpaceSize 设置ClassMetaspace大小,默认1g ...

March 1, 2024 · 1 min · jiezi

关于后端:Java-继承与多态代码重用与灵活性的巧妙结合

Java 继承(子类和超类)在 Java 中,能够从一个类继承属性和办法到另一个类。咱们将“继承概念”分为两类: 子类(child): 从另一个类继承的类超类(parent): 被继承的类 要从一个类继承,应用 extends 关键字。 示例: class Vehicle { protected String brand = "Ford"; // Vehicle 属性 public void honk() { // Vehicle 办法 System.out.println("Tuut, tuut!"); }}class Car extends Vehicle { private String modelName = "Mustang"; // Car 属性 public static void main(String[] args) { // 创立 myCar 对象 Car myCar = new Car(); // 在 myCar 对象上调用 honk() 办法(来自 Vehicle 类) myCar.honk(); // 显示来自 Vehicle 类的 brand 属性的值和来自 Car 类的 modelName 的值 System.out.println(myCar.brand + " " + myCar.modelName); }}输入: ...

February 29, 2024 · 2 min · jiezi

关于后端:Rocketmq-java-hello-world-入门案例

从零手写实现 mqrocketmq java 入门案例整体构造|____src| |____main| | |____java| | | |____com| | | | |____ryo| | | | | |____rocket| | | | | | |____demo| | | | | | | |____common| | | | | | | | |____consumer| | | | | | | | | |____Consumer.java| | | | | | | | |____productor| | | | | | | | | |____Productor.java| | |____resources| | | |____log4j.propertiesmaven 依赖pom.xml<dependencies> <!--rocketmq--> <dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>${rocketmq.version}</version> </dependency> <dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>rocketmq-common</artifactId> <version>${rocketmq.version}</version> </dependency> <dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>rocketmq-remoting</artifactId> <version>${rocketmq.version}</version> </dependency> <!--log--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency></dependencies>配置log4j.propertieslog4j.rootLogger=warn, stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[%t] %d{MM-dd HH:mm:ss,SSS} - %m%n代码Consumer.java/** * @author houbinbin * @on 17/1/2 */public class Productor { public static void main(String[] args) { DefaultMQProducer producer = new DefaultMQProducer("Producer"); producer.setNamesrvAddr("127.0.0.1:9876"); try { producer.start(); Message message = new Message("PushTopic", "push", "1", "Just fot test.".getBytes()); SendResult result = producer.send(message); System.out.println("id:" + result.getMsgId() + " result:" + result.getSendStatus()); message = new Message("PushTopic", "push", "3", "Just fot test.".getBytes()); result = producer.send(message); System.out.println("id:" + result.getMsgId() + " result:" + result.getSendStatus()); } catch (Exception e) { e.printStackTrace(); } finally { producer.shutdown(); } }}运行LOG如下: ...

February 29, 2024 · 2 min · jiezi

关于后端:Rocketmq-maclinux-安装笔记

从零手写实现 mqQuick Startquick start 须要64位操作系统,最好是Linux/Unix/Mac;64位JDK 1.6+;Maven 3.xGitScreenJDKhoubinbindeMacBook-Pro:aliyun-ons-client-java houbinbin$ java -versionjava version "1.8.0_91"Java(TM) SE Runtime Environment (build 1.8.0_91-b14)Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)下载和装置下载 RocketMQ从这里下载:https://github.com/alibaba/RocketMQ/releases,以后版本标签为 3.5.8 $ lsRocketMQ-3.5.8 RocketMQ-3.5.8.tar.gz装置$ pwd/Users/houbinbin/it/tools/rocketMQ/RocketMQ-3.5.8$ bash install.sh...而后咱们失去 To refactor, move this assembly into a child project and use the flag <useAllReactorProjects>true</useAllReactorProjects> in each moduleSet.[INFO] Building tar: /Users/houbinbin/IT/tools/rocketMQ/RocketMQ-3.5.8/target/alibaba-rocketmq-broker.tar.gz[INFO] ------------------------------------------------------------------------[INFO] Reactor Summary:[INFO][INFO] rocketmq-all 3.5.8 ................................. SUCCESS [ 48.565 s][INFO] rocketmq-remoting 3.5.8 ............................ SUCCESS [ 1.772 s][INFO] rocketmq-common 3.5.8 .............................. SUCCESS [ 1.348 s][INFO] rocketmq-client 3.5.8 .............................. SUCCESS [ 1.522 s][INFO] rocketmq-store 3.5.8 ............................... SUCCESS [ 0.815 s][INFO] rocketmq-srvutil 3.5.8 ............................. SUCCESS [ 0.139 s][INFO] rocketmq-broker 3.5.8 .............................. SUCCESS [ 0.951 s][INFO] rocketmq-tools 3.5.8 ............................... SUCCESS [ 0.889 s][INFO] rocketmq-namesrv 3.5.8 ............................. SUCCESS [ 0.373 s][INFO] rocketmq-example 3.5.8 ............................. SUCCESS [ 0.392 s][INFO] rocketmq-filtersrv 3.5.8 ........................... SUCCESS [ 0.337 s][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 59.323 s[INFO] Finished at: 2017-01-02T18:21:01+08:00[INFO] Final Memory: 52M/1042M[INFO] ------------------------------------------------------------------------环境配置确保以下环境变量正确设置:JAVA_HOME ...

February 29, 2024 · 2 min · jiezi

关于后端:Rocketmq-入门介绍

从零手写实现 mq具体介绍一下 rocketmqRocketMQ 是由阿里巴巴开发的分布式音讯队列零碎,它是一个低提早、高牢靠、高吞吐量的消息中间件。 RocketMQ 最后是作为阿里巴巴的外部我的项目进行开发的,起初成为了 Apache 软件基金会下的顶级我的项目,以 Apache 许可证 2.0 公布,使其成为一个凋谢、收费的开源我的项目。 以下是 RocketMQ 的一些次要个性: 分布式架构:RocketMQ 是基于分布式架构设计的,能够轻松地实现程度扩大以满足高吞吐量和大规模部署的需要。它反对多个音讯队列服务器(Broker)和多个音讯消费者,以实现负载平衡和高可用性。高可靠性:RocketMQ 提供了严格的消息传递保障,包含程序音讯、事务音讯、音讯重试等机制,确保音讯不会失落。它应用主从复制和同步刷盘等技术来保障音讯的可靠性。高吞吐量:RocketMQ 在设计上重视了高吞吐量的指标,通过优化网络通信、存储和音讯解决等方面的性能,实现了十分高的音讯处理速度。低提早:RocketMQ 的设计谋求低提早,可能疾速地将消息传递给消费者,并且反对优先级音讯以及批量发送等个性,进一步升高了消息传递的提早。灵便的音讯模型:RocketMQ 反对多种音讯模型,包含点对点(P2P)模型和公布/订阅(Pub/Sub)模型,能够满足不同场景下的需要。丰盛的性能:RocketMQ 提供了丰盛的性能和个性,包含音讯过滤、提早音讯、定时音讯、事务音讯等,能够满足各种简单的业务场景需要。可扩展性:RocketMQ 提供了丰盛的插件和扩大接口,能够不便地进行定制化开发和扩大,以满足特定业务需要。RocketMQ 是一个功能丰富、稳固牢靠、性能优异的分布式音讯队列零碎,广泛应用于互联网、物联网、大数据等畛域,为企业提供了牢靠的音讯通信基础设施。 为什么要用 rocketmq 呢?和 kafka/rabbitmq/activemq 等比照有哪些优缺点?应用 RocketMQ 的起因能够有很多,具体取决于你的业务需要、技术栈以及团队的偏好。 以下是应用 RocketMQ 的一些常见起因以及与其余音讯队列零碎(如 Kafka、RabbitMQ 和 ActiveMQ)进行比照的优缺点: 为什么要应用 RocketMQ? 高可靠性和稳定性:RocketMQ 提供了主从复制、同步刷盘等机制,确保音讯不会失落,可能满足对消息传递可靠性要求较高的场景。低提早:RocketMQ 谋求低提早的设计指标,可能疾速地将消息传递给消费者,实用于对提早要求较高的业务场景。高吞吐量:RocketMQ 通过优化网络通信、存储和音讯解决等方面的性能,实现了十分高的音讯处理速度,实用于须要解决大量音讯的场景。丰盛的性能:RocketMQ 提供了丰盛的性能和个性,如音讯过滤、提早音讯、定时音讯、事务音讯等,能够满足各种简单的业务场景需要。Apache 开源我的项目:RocketMQ 是 Apache 软件基金会下的顶级我的项目,具备凋谢、收费、社区沉闷等特点,受到了宽泛的关注和反对。与其余音讯队列零碎的比照优缺点: 与 Kafka 比照: 长处:Kafka 在大数据畛域有很高的知名度和使用率,实用于大规模数据处理和实时剖析等场景。毛病:相比 Kafka,RocketMQ 更加重视消息传递的可靠性和稳定性,对于一些对音讯可靠性要求更高的场景可能更适宜应用 RocketMQ。与 RabbitMQ 比照: 长处:RabbitMQ 在 AMQP(高级音讯队列协定)的反对上更加全面,实用于简单的消息传递场景,如分布式事务、音讯确认等。毛病:相比 RabbitMQ,RocketMQ 在分布式部署和程度扩大方面更加灵便和简略,实用于高并发、大规模的消息传递场景。与 ActiveMQ 比照: 长处:ActiveMQ 是一个成熟的 JMS(Java 音讯服务)实现,提供了丰盛的性能和协定反对,实用于 Java 生态系统中的消息传递场景。毛病:相比 ActiveMQ,RocketMQ 更加轻量级和高性能,实用于对消息传递性能和稳定性要求较高的场景。rocketmq 是如何保障音讯不失落的?RocketMQ 通过多种机制来确保音讯不会失落,次要包含以下几点: ...

February 29, 2024 · 1 min · jiezi

关于后端:蚂蚁流场景状态演进和优化

本文整顿自蚂蚁团体实时计算组技术专家闵文俊在 FFA 2023 核心技术(一)中 的分享,内容对于蚂蚁流场景状态演进和优化的钻研,次要分为以下三局部: 状态后端的演进优化与适配将来瞻望一. 状态后端的演进1. 蚂蚁状态后端的演进 在蚂蚁的生产环境中,最早有一套流计算零碎外部的我的项目,代号为 Kepler。在 Kepler 零碎实现了一套可插拔的状态后端存储系统。在咱们生产环境中应用最宽泛的是基于 Hbase 和 OceanBase 这种近程存储的状态后端,它的劣势在于 checkpoint 十分的快,因为流工作在计算的过程中,它的数据曾经写到近程存储中,并且它的 failover 也会比拟快,因为在 failover 的过程中,它不波及到数据的下载以及复原的过程。它也不依赖于本地磁盘,对于云化环境会比拟敌对。 并且在分布式存储系统中,个别都提供了拜访这些数据的 API,所以对于这些曾经存储在状态后端外面的数据是能够通过这些 API 间接拜访、查问进去,比方咱们线上会通过 Hbase 的 API 间接将咱们存储在这些零碎中的流工作的状态的 offset 间接裸露进去,这就相似于 Flink 外面的 qureyable state 这种能力。 它的劣势也比拟显著。首先,它的性能会比拟差。因为对于这种分布式存储系统,它所能提供的拜访提早,根本都是在毫秒级,而本地存储个别可能达到微秒级,所以这个时延就比拟高,它的整体的拜访 TPS 就比拟受限,个别不太适宜于大状态的工作。第二,它的稳定性会有余,因为它会受限于第三方服务的稳定性影响,它整体的 SLA 就不如本地存储。 2. 基于 RocksDB 本地状态后端 在咱们陆续从蚂蚁外部资源的流计算,逐渐切到社区的 Flink 的过程中,状态后端也就天然切换到 Flink 自带的基于 RocksDB 的本地状态存储中。 RocksDB 状态存储也是当初应用的十分多的状态存储,它的劣势次要是,它是基于 RocksDB 这种高性能的本地 KVstore,所以它的状态拜访的延时非常低,它能满足工夫敏感比拟高的工作吞吐的需要。稳定性更好。 它的劣势在于,第一因为 RocksDB 自身是基于 LSMtree 这样的构造的,就义了肯定的读的性能,来满足它的写的性能。然而当咱们写入的前台流量比拟大的时候,它的后盾的 compaction 会去逐渐占用更多的机器的 IO 和 CPU 资源,而影响到前台的写入以及拜访的需要,体现的比拟显著. 在线上的工作中会看察看到的景象,工作在高峰期的时候,会看到它的吞吐反而会有降落的体现。 ...

February 29, 2024 · 5 min · jiezi

关于后端:深入浅出JVM十八之并发垃圾收集器G1

在这篇文章 深入浅出JVM(十六)之三色标记法与并发可达性剖析 中,咱们曾阐明过GC线程和用户线程并发执行导致的对象隐没问题,能够应用增量更新或原始快照的形式来解决 上文深入浅出JVM(十七)之并发垃圾收集器CMS中形容过应用增量更新的CMS,本文将介绍应用原始快照的G1垃圾收集器 Garbage FirstG1 全称 Garbage First 面向服务端的垃圾收集器,G1诞生是为了在提早可控的状况下尽可能高的吞吐量 RegionG1 不再应用分代收集算法,把Java堆内存分为多个大小相等的区域(Region),面向堆内存任何局部来组成区(Region)进行收集,哪块内存垃圾最多,收益最大就回收哪块 Region分为新生代Eden、新生代Survive、大对象Humongous 大多数状况下Humongous被当成老年代 当大对象太大,一个Humongous不够时,应用间断多个Humongous存储 每个区域设计2个TAMS(Top at Mark Start)指针,把区域中一部分空间划分进去用来为新对象分配内存(指针碰撞,内存规整) G1从整体上能够看成应用标记-整顿算法,从部分上能够看成应用区域间复制算法 执行过程与流程图G1采纳原始快照来解决GC线程与用户线程并发时的对象隐没问题 G1收集器在后盾保护一个优先级队列跟踪各个区域中的垃圾回收价值(回收垃圾的大小和回收工夫的状况) 依据-XX:MaxGCPauseMillis用户规定的收集进展工夫来优先回收垃圾回收价值最大的区域 执行过程初始标记 : 标记GC Roots能间接关联的对象,批改TAMS指针(进展用户线程,耗时短)并发标记 : 从GC Roots间接关联对象开始遍历整个援用链的过程(GC线程与用户线程并发执行耗时长),扫描完还要解决原始快照记录在并发时有援用变动的对象最终标记 : 解决并发阶段遗留下来的大量原始快照记录(进展用户线程,耗时短)筛选回收 : 更新区域的垃圾回收价值,把各个区域的垃圾回收价值(要算老本:回收工夫)在优先级队列中排序,依据用户所冀望的进展工夫制订回收打算,把要回收的那片区域存活的对象复制到空区域中(复制对象要暂停用户线程,GC线程并行执行)如果冀望进展工夫设置太短(不符合实际),因为进展工夫短,回收垃圾速度<为新对象分配内存速度,会导致堆满Full GC反而会升高性能 参数-XX:+UseG1GC 应用G1收集器 -XX:G1HeapRegionSize设置每个region大小 -XX:MaxGCPauseMillis设置预期进展工夫 (默认200ms,最好不要太小) -XX:ParallelGCThread设置GC线程数 -XX:ConcGCThreads设置并发标记线程数 -XX:InitiatingHeapOccupancyPercent设置触发老年代GC的堆占用率阈值 特点长处整体:标记-整顿、部分:复制,不会产生内存碎片从用户冀望工夫来回收垃圾价值最高的垃圾原始快照的益处(记录旧援用,不须要增加新援用记录,缩小并发标记、从新标记阶段的耗费)毛病因为有很多区域,跨区域援用对象问题频繁呈现,每个区域要保护记忆集(Key:别的区域地址 Value:汇合存储卡表的索引号),卡表实现简单(其余卡表:我指向谁,这里的卡表:我指向谁+谁指向我),所以占用内存更大执行负载大(写屏障操作简单) 写后屏障保护简单的卡表 原始快照的害处(须要记录旧援用):写前屏障跟踪并发指针变动,在用户程序运行中产生有跟踪援用变动带来的额外负担 CMS写屏障能够间接同步,而G1写屏障太简单要把写前屏障和写后屏障中做的事放到队列中,异步解决 总结本篇文章深入浅出的介绍G1并发垃圾收集器Region、执行过程、流程图、参数、特点等常识 G1不应用分代算法,将内存分为Region,Region分为Eden、Survive、Humongous,从部分能够看成复制算法,整顿上看成标记-整顿算法 G1初始标记枚举GC根节点,在并发标记中应用原始快照解决对象隐没问题,最终标记后应用优先级队列优先回收价值高的region G1不会产生内存碎片,可能在冀望的低提早中实现价值最大的清理,但保护跨代援用、写后屏障等开销大 内存较大、处理器较多、冀望低提早、面向服务端的垃圾收集器能够抉择G1 最初(一键三连求求拉~)本篇文章将被支出JVM专栏,感觉不错感兴趣的同学能够珍藏专栏哟~ 本篇文章笔记以及案例被支出 gitee-StudyJava、 github-StudyJava 感兴趣的同学能够stat下继续关注喔\~ 有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下\~ 关注菜菜,分享更多干货,公众号:菜菜的后端私房菜 本文由博客一文多发平台 OpenWrite 公布!

February 29, 2024 · 1 min · jiezi

关于后端:Pingora快速入门负载均衡器

疾速入门:负载均衡器介绍 本疾速入门展现了如何应用 pingora 和 pingora-proxy 构建一个简略的负载均衡器。 负载均衡器的指标是对于每个传入的 HTTP 申请,以循环形式抉择两个后端之一: https://1.1.1.1和https://1.0.0.1 。 构建根本的负载均衡器 为咱们的负载均衡器创立一个新的 Cargo 我的项目。名称为 load_balancer cargo new load_balancer包含 Pingora Crate 和根本依赖项 在您的我的项目cargo.toml文件中将以下内容增加到您的依赖项中 async-trait="0.1"pingora = { version = "0.1", features = [ "lb" ] }创立 pingora 服务器 首先,让咱们创立一个 pingora 服务器Server。Server是一个能够托管一个或多个服务的过程。Server负责配置和 CLI 参数解析、守护过程、信号处理以及失常重启或敞开。 Server首选用法是在main()函数中初始化,应用run_forever()生成所有运行时线程并阻塞主线程,直到服务器退出。 use async_trait::async_trait;use pingora::prelude::*;use std::sync::Arc;fn main() { let mut my_server = Server::new(None).unwrap(); my_server.bootstrap(); my_server.run_forever();}这将编译并运行,但它不会做任何乏味的事件。 创立负载均衡器代理 接下来让咱们创立一个负载均衡器。咱们的负载均衡器保留上游 IP 的动态列表。pingora-load-balancingcrate曾经提供了构造体LoadBalancer,并提供了常见的抉择算法,例如循环法和散列法。所以咱们就用它吧。如果用例更简单或须要定制服务器抉择逻辑,用户能够简略地在此办法中自行实现。 pub struct LB(Arc<LoadBalancer<RoundRobin>>);为了使服务器成为代理,咱们须要为其实现ProxyHttp特色。 任何实现ProxyHttp特色的对象实质上定义了如何在代理中解决申请。ProxyHttp特色中惟一须要的办法是upstream_peer(),该办法用于返回申请应代理到的地址。 在upstream_peer()办法中,咱们应用LoadBalancer的select()办法来轮询上游IP。在这个例子中,咱们应用HTTPS连贯到后端,所以咱们还须要指定 use_tls,并在构建Peer对象时设置SNI。 #[async_trait]impl ProxyHttp for LB { /// For this small example, we don't need context storage type CTX = (); fn new_ctx(&self) -> () { () } async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result<Box<HttpPeer>> { let upstream = self.0 .select(b"", 256) // hash doesn't matter for round robin .unwrap(); println!("upstream peer is: {:upstream?}"); // Set SNI to one.one.one.one let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string())); Ok(peer) }}为了让 1.1.1.1 后端承受咱们的申请,必须存在主机申请头。增加申请头能够在upstream_request_filter()回调中实现,该回调会在与后端建设连贯之后、发送申请头之前批改申请头。 ...

February 29, 2024 · 3 min · jiezi

关于后端:Elasticsearch使用实战以及代码详解

Elasticsearch 是一个应用 Java 语言编写、恪守 Apache 协定、反对 RESTful 格调的分布式全文搜寻和剖析引擎,它基于 Lucene 库构建,并提供多种语言的 API。Elasticsearch 能够对任何类型的数据进行索引、查问和聚合剖析,无论是文本、数字、天文空间、结构化还是非结构化的。Elasticsearch 的外围性能是搜寻,它能够对数据进行分词匹配、相关性评分、高亮显示等操作,返回相关度高的后果列表。Elasticsearch 也能够用作数据分析,它能够对数据进行统计、分类、聚类等操作,返回聚合后果或图表。 本文将用我开源的 waynboot-mall 我的项目作于代码解说,Elasticsearch 版本是 7.10.1。 waynboot-mall 是一套全副开源的微商城我的项目,蕴含三个我的项目:经营后盾、H5 商城和后端接口。实现了一套残缺的商城业务,有首页展现、商品分类、商品详情、sku 详情、商品搜寻、退出购物车、结算下单、支付宝/微信领取、订单列表、商品评论等一系列性能。本文纲要如下, 利用场景Elasticsearch 的典型利用场景有以下几种: 全文搜寻:Elasticsearch 提供了全文搜寻的性能,实用于电商商品搜寻、App 搜寻、企业外部信息搜寻、IT 零碎搜寻等。例如咱们能够为每一个商品作为文档保留进 Elasticsearch,而后应用 Elasticsearch 的查询语言来对文档进行分词匹配、相关性评分、高亮显示等操作,返回相关度高的后果列表。日志剖析:Elasticsearch 能够用来收集、存储和剖析海量的日志数据,如我的项目日志、Nginx log、MySQL Log 等,往往很难从繁冗的日志中获取有价值的信息。Elasticsearch 可能借助 Beats、Logstash 等工具疾速对接各种常见的数据源,并通过集成的 Kibana 高效地实现日志的可视化剖析,让日志产生价值。运维监控:Elasticsearch 也能够用来监控和治理 IT 零碎的运行状态和性能指标,如 CPU、内存、磁盘、网络等。能够应用 Beats、Logstash 将这些数据实时采集并索引到 Elasticsearch 中,而后通过 Kibana 构建自定义的仪表盘和告警规定,实现实时的运维监控和预警。数据可视化:Elasticsearch 与 Kibana 的联合提供了弱小的数据可视化能力,能够应用 Kibana 来创立各种类型的图表和仪表盘,展现 Elasticsearch 中存储或聚合的数据,如直方图、饼图、地图、工夫线等。还能够应用 Kibana 的 Canvas 性能来制作动静的数据展现页面,或者应用 Kibana 的 Lens 性能来进行交互式的数据摸索。waynboot-mall 商城抉择应用 Elasticsearch 作为搜索引擎,负责对商品数据进行索引和检索,抉择 Elasticsearch 的起因有以下几点, ...

February 29, 2024 · 3 min · jiezi

关于后端:统信软件统一操作系统-UOS-代言人

这是ren_dong的第32篇原创1、DeepinDeepin:最受欢迎的民用国产操作系统2008 年,Deepin 操作系统最早版本正式公布,是由深之度创始人刘闻欢组织团队研发的基于 Debian 的本地化 Linux 操作系统2011 年,武汉深之度科技有限公司成立,开始产品研发和团队组件 2014 年,Deepin 操作系统入围中央政府集体操作系统洽购名单2015 年,公司实现首轮融资后正式进入商业化运作。2017 年,Deepin进入国内开源操作系统前十名。依据 Distrowatch,Deepin 关注度排在寰球 Linux 操作系统第十,评分 8.89,是 Distrowatch 上排名最高的中国 Linux 操作系统发行版。 目前 Deepin 零碎已反对超过 40 种不同的语言,参加的社区用户和开发者超过 300 人。 2、统信软件深度科技牵手诚迈科技,成立统信软件2019年11月25日,诚迈科技布告拟以全资子公司武汉诚迈100%股权作价人民币2.04亿元,深度科技股东拟以其持有的100%股权作价人民币2.55亿元,独特以股权对统信软件增资。诚迈科技持有统信软件44.44%的股权,武汉诚迈与深度科技成为统信软件的全资子公司。 两大“杀手锏”绑定华为:华为PC预装了Deepin操作系统。深度科技曾经为华为TaiShan硬件平台打造了全线操作系统软件产品,针对华为鲲鹏平台陆续公布了三款操作系统产品。成为UOS的代言人:目前UOS次要由统信软件基于Deepin操作系统来打造。国产UOS操作系统曾经正式取得了工信部的测试认证。 3、UOS依靠深度 Deepin OS,打造商业化对立操作系统 UOS UOS即“对立操作系统” ,是由统信软件开发的一款基于 Linux 内核的操作系统,分为对立桌面操作系统和对立服务器操作系统。 对立桌面操作系统以桌面利用场景为主,对立服务器操作系统以服务器撑持服务场景为主。UOS 是以 Deepin OS 为根底开发的,能够了解为 Deepin 是社区化版本,而 UOS 是 Deepin 的商业化版本,UOS 与Deepin 的关系与 Fedora 和 Redhat RHEL 相似。目前 UOS 曾经实现了对龙芯、飞腾、鲲鹏、申威、海光、兆芯六大国产 CPU 的适配,提供 x86、ARM、龙芯、服务器多个镜像版本 End码字不易,欢送关注、点赞,感激反对! 本文由mdnice多平台公布

February 29, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十七之并发垃圾收集器CMS

上篇文章介绍用户线程与GC线程并发执行时可能产生的问题以及应用三色标记法演示原始快照和增量更新两种解决方案 这篇文章将次要介绍并发垃圾收集器中的CMS,其中CMS应用增量更新来解决对象隐没问题,如果不理解增量更新的同学能够查看上篇文章深入浅出JVM(十六)之三色标记法与并发可达性剖析 前言前文形容过,当GC时须要枚举的GC根节点须要极短的进展(STW) 而在遍历GC援用链时,如果用户线程是进展的,那么不会扭转援用,GC线程遍历标识即可 但随着堆内存中对象的增多,援用链会越来越长,如果继续让用户线程进展,在某些须要低提早的场景是不现实的 因而心愿能在这个环节让用户线程和GC线程可能并发执行,并发执行就会存在扭转对象援用,可能导致对象隐没问题,其中能够应用增量更新和原始快照的形式解决,而CMS应用的就是增量更新 Concurrent Mark SweepCMS全称Concurrent Mark Sweep 并发标记革除收集器 CMS是老年代收集器,采纳标记-革除算法,年老代罕用ParNew收集器,以最短进展工夫(低提早)为指标的收集器 CMS并没有应用标记-整顿算法,因为标记、清理阶段是和用户线程并发执行的,如果应用标记-整顿算法可能会导致挪动援用的地位导致出错 执行步骤初始标记: 标记GC Roots间接关联的对象(STW工夫极短)并发标记: 从GC Roots间接关联对象开始遍历整个援用链的过程(耗时长,不须要进展用户线程,用户线程与GC线程并发执行)从新标记: 应用增量更新防止对象隐没问题,修改并发标记期间改变的对象(须要STW,耗时比步骤1长,比步骤2短)并发革除: 清理标记阶段判断已死亡的对象、重置状态等(该阶段也是并发执行)执行图 参数设置-XX:UseConcMarkSweepGC 老年代应用CMS垃圾收集器,新生代应用ParNew收集器-XX:CMSInitiatingOccupancyFraction 设置老年代应用多少空间时开始垃圾回收 如果设置的太高,不够内存调配,不能满足并发执行,就会解冻用户线程启动Serial Old收集器,进展工夫就会变长如果内存增长迟缓能够设置高一些,如果内存增长很快就要设置低一些 默认92%-XX:+UseCMSCompactAtFullCollection 指定在FULL GC后是否对内存进行压缩整顿开启后,通过-XX:CMSFullGCsBeforeCompaction设置执行多少次FULL GC后进行内存压缩整顿-XX:ParallelCMSThreads 设置GC线程数量特点长处:进展工夫短 只在初始标记,从新标记时STW 并发执行 工夫长的并发标记和并发清理与用户线程,放慢响应速度,晋升用户体验 毛病:吞吐量升高 在处理器核数少时,GC线程与用户线程并发执行(应用i-CMS解决:缩小GC线程独占工夫,垃圾回收工夫变长,对用户线程执行影响变小) 无奈解决浮动垃圾 增量更新通过记录新增援用来防止对象隐没问题,可能呈现浮动垃圾(不能在这一次的GC中被回收,只能下一次GC时被回收) CMS不能等老年代满了再垃圾回收,因为与用户线程并发执行,所以须要留一部分内存 内存碎片多 屡次垃圾回收后进行一次标记-整顿算法,采纳替补计划Serial Old 总结本文依据并发垃圾收集器CMS深入浅出的解析CMS执行流程、优缺点以及配置参数等 CMS是一款主打低提早、应用标记-革除算法的老年代并发垃圾收集器,年老代常应用ParNew CMS在初始标记时进行STW,接下来遍历援用链时与用户线程并发执行,而后让用户线程短暂STW应用增量更新进行从新标记,最初在并发进行清理、重置等工作 CMS的特点是在遍历援用链、清理时并发执行,可能使用户线程的进展工夫变短;然而带来吞吐量的升高,并且增量更新会导致浮动垃圾的呈现,因为老年代应用标记-革除算法,不整顿内存将会导致大对象无奈存储,替补计划是应用Serial Old单线程标记-整顿 如果老年代内存不足或须要整顿内存时,会应用Serial Old 单线程解决,这可能导致提早更高,在高版本中曾经有G1等其余垃圾收集器代替CMS,CMS在JDK14时被移除 最初(一键三连求求拉~)本篇文章将被支出JVM专栏,感觉不错感兴趣的同学能够珍藏专栏哟~ 本篇文章笔记以及案例被支出 gitee-StudyJava、 github-StudyJava 感兴趣的同学能够stat下继续关注喔\~ 有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下\~ 关注菜菜,分享更多干货,公众号:菜菜的后端私房菜 本文由博客一文多发平台 OpenWrite 公布!

February 29, 2024 · 1 min · jiezi

关于后端:Java-包和-API-深度解析组织代码避免命名冲突

Java 包和 APIJava 中的包 用于将相干的类分组在一起。能够将其视为文件目录中的一个文件夹。咱们应用包来防止名称抵触,并编写更易于保护的代码。 包分为两类: 内置包(来自 Java API 的包)用户定义的包(创立本人的包)内置包 Java API 是一个事后编写的类库,能够在 Java 开发环境中收费应用。 该库蕴含用于治理输出、数据库编程等等的组件。残缺的列表能够在 Oracle 的网站上找到: 该库分为包和类。这意味着您能够导入单个类(以及其办法和属性),或者导入蕴含属于指定包的所有类的整个包。 要应用库中的类或包,您须要应用import关键字: // 导入单个类import package.name.Class;// 导入整个包import package.name.*;导入类 如果找到要应用的类,例如Scanner类(用于获取用户输出),请编写以下代码: // 导入 Scanner 类import java.util.Scanner;在下面的示例中,java.util 是一个包,而 Scanner 是 java.util 包的一个类。 要应用 Scanner 类,请创立该类的对象,并应用 Scanner 类文档中提供的任何可用办法。在咱们的例子中,咱们将应用 nextLine() 办法,该办法用于读取一整行: // 应用 Scanner 类获取用户输出import java.util.Scanner;class MyClass { public static void main(String[] args) { Scanner myObj = new Scanner(System.in); System.out.println("Enter username"); String userName = myObj.nextLine(); System.out.println("Username is: " + userName); }}导入包 ...

February 28, 2024 · 1 min · jiezi

关于后端:一位有着近-10-年-iOS-开发经验的全职爸爸如何高效管理时间

名字: Mindr 开发者 / 团队: Florian Vates 平台: iOS, iPadOS, Android 正在开发中 请简要介绍下这款产品有没有发现自己总是一直推延待办事项的告诉? Mindr 以一种全新的办法来解决这个问题,它直观的界面设计将待办事项的进度间接显示在桌面上,就像查看 Apple 的电池小组件一样,你只须要轻松一瞥便能晓得剩余时间。 给 Mindr 一个机会,它的成果会让你大吃一惊! 哪个霎时让你决定开发这款产品?在我意识到本人总是无限期推延一些不会带来严重后果的工作,并且开始失去对它们逾期工夫的跟踪时,突然脑中灵光一闪——我发现传统的告诉揭示对这类工作并不见效,于是我决定打造一个更无效的解决方案。 相比于同类产品,你感觉它有什么特别之处?大多数待办事项 App 都是在工作到期时揭示你,让你立即去实现,但往往那并非是实现工作的最佳时机。与之不同,Mindr 采纳视觉进度显示,让你对工作是否逾期以及逾期时长高深莫测,从而激发你的紧迫感。 你尝试过哪些渠道推广它?过程中有什么播种吗?目前咱们次要通过公开产品构建的过程(Build in Public)进行推广,并与多家观赏咱们这种翻新形式的科技媒体单干,他们对于咱们在这个竞争激励的市场带来的新思路示意赞叹,并对 Mindr 进行了报道。 公布这款产品至今,有哪些反馈让你印象粗浅?让我感到十分开心的是,许多患有多动症(ADHD)的用户通知我,这款 App 极大地帮忙他们进步了对工作的专一度。因为他们可能继续地看到这些工作,并感触到紧迫感。看到我的产品能帮忙他们解决最头痛的问题,真的让我感到快慰。 你是如何获取灵感,验证它的可行性,并投入开发和设计的?我有一份全职工作,还须要关照家庭以及在教堂做义工,因而我的工夫十分无限,就更不用说业余爱好了。尽管如此,我还是致力每天至多挤出一个小时来解决副业我的项目(Side Projects)。 工夫的贵重让我必须高效地利用每一分钟,在 App 开发方面的教训帮忙我在编程上节俭了不少工夫,因而优先级划分成为我工作的重点。我用 Sorted 3 疾速记下忽然冒出的工作和想法,之后再进行整顿和优先排序。 但我通常对此并不会过于严格,毕竟我还是想享受创作的乐趣。如果我临时不想做某件事,我会依据理论状况进行调整。在广告公司超过 9 年的工作教训,让我学会了如何无效地区分轻重缓急。 因而,我只开发那些能解决我集体问题的 App,这也是我对市场验证不太刻薄的起因,因为这些 App 原本就是为了我本人而制作的。与此同时,这也让我对实现和欠缺这些 App 充斥能源,这是一个意想不到的益处。 在设计方面,我有本人保持的格调,并尝试让它实用于其余 App。我偶然也会从 Dribbble 上寻找灵感,作为一名有近 10 年教训的 iOS 开发者,启动新我的项目对我来说曾经轻车熟路。 有哪些产品你感觉应该被更多用户晓得?除了后面提到的 Sorted 3 外,还有一个可能不太为人所知的 App 是 Rotato,我用它来制作利用性能的动画演示。另一个值得一提的是 Wishkit,它可能帮忙收集用户的性能需要,这对于确定产品的优先级十分有帮忙。尽管我曾经构建了本人的一套零碎,但对于那些不想本人入手的人来说,应用像 Wishkit 这样的服务是一个不错的抉择。 ...

February 28, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十六之三色标记法与并发可达性分析

上篇文章深入浅出JVM(十五)之垃圾回收器(上篇)介绍性能指标吞吐量和提早、串行收集器、并行收集器以及吞吐量优先收集器 为了更好的形容并发垃圾收集器,本篇文章将先深入浅出的介绍三色标记法以及并发可达性剖析遇到的问题以及解决方案 三色标记法JVM中应用可达性剖析算法来判断对象是否持续应用 当对象不可达时,执行过finalize办法或者finalize办法搭不上援用链时能力回收这些对象 不了解如何判断对象不再应用的同学能够看这篇文章深入浅出JVM(十一)之如何判断对象“已死” 为了更好的阐明并发可达性剖析,咱们应用三色标记法模仿,先阐明三色标记法 三色标记法的色彩、流程阐明三色标记法的三种色彩阐明 彩色:以后对象被扫描过,并且它援用的对象也被扫描 灰色:以后对象被扫描过,至多有一个援用未被扫描 红色:以后对象未被扫描过 GC 根节点总是彩色的,因为它们隐式可达 扫描时,从GC Roots节点(灰色)开始,将它援用的对象全染成灰色,再将本人染成彩色,再从灰色对象汇合中遍历上述操作,相似树的层序遍历 当扫描结束时,如果对象仍旧是红色阐明这个对象是不可达对象 比方图中的a变成彩色,阐明a援用的对象b曾经被扫描了;而b是灰色,阐明b至多有一个援用的对象没被扫描(b援用的c就还未被扫描) b将援用的c染成灰色后,将本人染成彩色,再从灰色对象汇合中取出对象c进行后续操作 并发可达性剖析当GC、用户线程并发执行时,就会呈现对象援用可能扭转的状况,可能造成浮动垃圾和对象失落的状况 浮动垃圾一种状况会把本来死亡的对象改成活的对象,成为浮动垃圾,下次再回收掉 比方c将援用的d、e染成灰色后将本人染成彩色 因为还未扫描完结,用户线程将c援用e删除了c.e = null,原本e没有被援用应该变成垃圾 但因为并发执行,后续GC线程从灰色对象汇合中获取d、e进行解决,最终会被染黑,e就变成浮动垃圾,本轮GC不会回收e 浮动垃圾的呈现能够被承受,本轮不GC,下次GC也会进行回收 对象失落另一种状况会把本来存活的对象变成死亡的对象从而进行回收,非常危险 在从灰色对象拿出对象c 解决前,用户线程将c援用e删除c.e = null,后续c就不会将e染成灰色,只将d染成灰色 解决完对象c后,用户线程批改援用,让对象b援用对象eb.e = e,对象e变成须要应用的对象,但最终解决完d后,对象c仍旧是红色 这种状况下就会产生对象失落,对象c可能被GC回收,这种状况是危险的,不容许呈现 通过钻研表明对象隐没须要满足的条件: 插入一条或多条从彩色对象到红色对象的新援用删除全副从灰色对象到该红色对象的间接或间接援用只须要毁坏其中一条就能够防止对象隐没 增量更新和原始快照别离毁坏条件1、2 增量更新和原始快照会借助写屏障来解决,写屏障能够了解成AOP(在执行外围办法的前、后能够执行其余操作)  //写前屏障解决 //执行外围办法 //写后屏障解决增量更新增量更新应用写后屏障,某个对象新增的援用时,将该对象记录下来,扫描完后将这个对象变为灰色对象从新扫描,在后续这个从新扫描的阶段须要用户线程STW 应用从新扫描,短暂STW的形式毁坏条件一 用下面那张对象失落的图举例的话,就是b对象在新增e援用时,后续会将b对象变为灰色从新扫描 从新扫描后,e对象最终也染黑 原始快照原始快照应用写前屏障,在删除援用前保留要删除的援用,在扫描结束后将这些删除的援用变为灰色对象从新扫描 原始快照毁坏条件二,将红色对象变为灰色 并且GC开始后产生新增援用时,应用TAMS(Top at Mark Start)指针对新增援用进行记录(隐式可达) 对象c删除援用的对象e时记录对象e,扫描结束时如下 STW从新扫描时,会将记录的对象e变灰色从新扫描,对象e变成了浮动垃圾;而新增的对象g用TAMS指针隐式可达间接变黑 因为被删除援用变灰,它可能变成浮动垃圾 总结本篇文章围绕并发的可达性剖析深入浅出的解析三色标记法、并发可达性剖析可能呈现的浮动垃圾,对象失落问题以及解决对象失落问题的增量更新、原始快照两种形式 在三色标记法中,彩色代表曾经扫描实现、灰色代表至多有一个援用未扫描、红色代表还未扫描,GC根节点默认彩色隐式可达 三色标记法从GC根节点开始将援用对象变成灰色并放入灰色汇合,并将本人变成彩色,接着再从灰色汇合中取出下一个对象进行解决,直到灰色汇合为空,还是红色的对象就是不可达对象 用户、GC线程并发执行时,可能扭转对象的援用关系,可能造成浮动垃圾、对象隐没的问题;浮动垃圾能够承受,下次GC会进行回收,然而对象隐没是不能承受的 对象隐没产生的两个条件是彩色对象新增到红色对象的援用和删除所有灰色对象到红色对象的间接/间接援用 增量更新应用写后屏障毁坏条件一,记录新增红色对象援用的彩色对象,扫描结束后STW将这个彩色对象变为灰色对象从新扫描 原始快照应用写前屏障毁坏条件二,记录被删除的红色对象,应用TAMS指针让新增援用隐式可达,扫描完笔后STW将记录的红色对象变成灰色对象从新扫描,并且将隐式可达的对象变黑 最初(一键三连求求拉~)本篇文章将被支出JVM专栏,感觉不错感兴趣的同学能够珍藏专栏哟~ ...

February 28, 2024 · 1 min · jiezi

关于后端:多数据源-ibatisbindingBindingException-Invalid-bound-statement

异样原本 springboot 配置 mysql 配置失常,起初新退出了其余数据源,发现报错: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)解决方案多数据源配置下,解决 org.apache.ibatis.binding.BindingException Invalid bound statement (not found)问题次要查看文件1、查看mybatis.xml文件namespace名称是否和Mapper接口的全限定名是否统一 2、查看Mapper接口的办法在mybatis.xml中的每个语句的id是否统一 3、查看Mapper接口办法返回值是否匹配select元素配置的ResultMap,或者只配置ResultType 4、查看yml文件中的mapper的XML配置门路是否正确 5、Mybatis中接口与映射文件肯定要同名或者必须在同一个包下,这个我没试过,如同是能够不同名的。 6、配置数据源的SqlSessionFactoryBean要应用MyBatisSqlSessionFactoryBean,这个也是鬼扯,MybatisPlus和Mybatis分分明再说 7、编译没有把XML拷贝过去,能够用这招: <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources></build>8、 启动会默认通过org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration * 类,咱们是自定义的,所以须要排除MybatisAutoConfiguration @SpringBootApplication(exclude = MybatisAutoConfiguration.class)9、Mapper接口文件,不同数据源须要搁置在不同包上面。 可能的起因都在这里了,各位慢用!!! 附上SqlSessionFactoryBean代码 ds1.java: package com.****.****.Configurer; import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.boot.jdbc.DataSourceBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @Configuration@MapperScan(basePackages = {"com.***.***.Mapper.ds1"}, sqlSessionFactoryRef = "ds1SqlSessionFactory")public class MybatisDS1Config { @Bean(name = "ds1DataSource") @ConfigurationProperties(prefix = "spring.datasource.ds1") public DataSource dataSource() { return DataSourceBuilder.create().build(); } /** * 配置事务管理器,不然事务不起作用 * * @return */ @Bean public PlatformTransactionManager transactionManagerDS1() { return new DataSourceTransactionManager(this.dataSource()); } @Primary @Bean(name = "ds1SqlSessionFactory") public SqlSessionFactoryBean ds1sqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath*:mapping/ds1/*.xml")); sqlSessionFactoryBean.setTypeAliasesPackage("com.***.***.Entity"); sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); return sqlSessionFactoryBean; /** * 这里在applications.properties外面配置了 * mybatis.type-aliases-package=com.jwt.springboot.dao * mybatis.mapper-locations=classpath:mapper/*Mapper.xml * 但多数据源状况下执行sql总会报:org.apache.ibatis.binding.BindingException: * Invalid bound statement (not found)........ * 起因是 this.mapperLocations 为null * * 注!!!!这里有大坑, 因为这里是自定义的sqlSessionFactoryBean,所以导致 * 没有启动时没有通过org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration * 类的sqlSessionFactory(DataSource dataSource)办法主动拆卸sqlSessionFactoryBean * 自定义的sqlSessionFactoryBean所以也没设置mapperLocations * 故自定义实例化sqlSessionFactoryBean这里须要手动设置mapperLocations * 可参考:https://developer.aliyun.com/article/754124 */ }}ds2,java ...

February 28, 2024 · 2 min · jiezi

关于后端:mybatis-selectKey-赋值未生效

问题mybatis 应用中,发现 selectKey 赋值没有失效。 为什么呢? Statement配置如下: <insert id="insertStatemnet" parameterType="User"> insert into user ( user_name ) values (#{user#userName}) <selectKey resultType="long" order="AFTER" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> </insert>Dao 层代码如下public interface UserMapper{ int insert(@Param(user) User user);}class User{ long id; String userName; ...getter/setter}User user = userMapper.insert(user);user.getId() 获取的后果等于0应用Mybatis Insert User表,应用selectKey获取LAST_INSERT_ID() ,赋值给user的id属性,发现id属性值未被set进去,user.getId() 获取的后果等于0,会话的LAST_INSERT_ID() 曾经到远远超过0了,返回0显著是不对的。 对于LAST_INSERT_ID() 能够参考 LAST_INSERT_ID 文章。 开始探索为什么?属性值获取到的是0,要么是SELECT LAST_INSERT_ID() sql未执行,应用了id long类型的默认值0,要么是执行了但获取到的值是0,或者是Mybatis set对象id属性值的时候没set进去。 Mybatis应用SelectKeyGenerator解决selectKey标签,从这里开始动手 private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) { try { if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) { String[] keyProperties = keyStatement.getKeyProperties(); final Configuration configuration = ms.getConfiguration(); final MetaObject metaParam = configuration.newMetaObject(parameter); if (keyProperties != null) { Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE); List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); if (values.size() == 0) { throw new ExecutorException("SelectKey returned no data."); } else if (values.size() > 1) { throw new ExecutorException("SelectKey returned more than one value."); } else { MetaObject metaResult = configuration.newMetaObject(values.get(0)); ... setValue(metaParam, keyProperties[0], values.get(0)); .... } } } } catch (ExecutorException e) { throw e; } catch (Exception e) { throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e); } }验证发现keyExecutor.query获取到的values是[100],阐明SELECT LAST_INSERT_ID() 查问没问题,那问题必然呈现在上面的setValue办法外面。 ...

February 28, 2024 · 3 min · jiezi

关于后端:分布式系统设计-从1千到10亿用户的跨越

随着用户增长,分布式系统的架构也须要随之演进。本文介绍了在用户从1千增长到10亿的过程中,零碎架构须要采纳的技术以及随之做出的扭转。原文: Distributed System Design — Scaling from 1K -10K, 10K-100K, 100K-1M, 1M to 100M and 10M to 1B users. 构建分布式系统最具挑战性的方面之一是扩大零碎以解决不同级别的用户流量,本文将探讨分布式系统的用户数量从1千扩大到10亿时所波及的罕用技术和架构衡量,还将针对每种规模提供进一步阐明剖析。 用户数量从1千扩大到1万:这种规模的零碎绝对简略,只需一台服务器或小型服务器集群即可解决。次要挑战有: 确保服务器可用性(非高可用性)和可靠性,现阶段能够只用一台服务器。在这个阶段,只须要一个中型到大型的Azure/AWS/GCP VM就足够了。优化服务器性能和提早。根本平安和认证机制。能够在这种规模上应用的一些技术是: 应用数据库来存储和检索数据。应用SSL/TLS对客户端和服务端之间的通信进行加密。应用OAuth或JWT对用户进行身份验证并受权其操作。用户数量从1万扩大到10万:在这种规模下,零碎开始面临更多挑战,须要更多资源,也更加简单。次要挑战有: 解决多个用户的并发申请和连贯。扩大数据库以解决更多的数据和查问。应用负载均衡器在服务器之间调配接管到的申请。解决系统故障和谬误。监控和记录零碎行为和性能。在这种规模下能够应用的一些技术包含: 应用缓存来缩小服务器负载并缩短响应工夫。应用程度扩大来增加更多服务器,以解决更多申请和连贯。应用分片或分区在多个数据库服务器或群集之间宰割数据。应用复制或备份确保故障状况下的数据一致性和可用性。应用音讯队列或Pub/Sub子系统来解耦零碎组件并解决异步事件。应用应用程序性能监控(APM)工具或日志框架来收集和剖析零碎指标和日志。用户数量从10万扩大到100万:在这种规模下,零碎变得更加简单,须要进行更多的优化和调整。次要挑战有: 管理系统分布式组件之间的网络提早和带宽。均衡服务器和数据库之间的负载。解决零碎热点和瓶颈问题。确保分布式环境中的数据完整性和安全性。在这种规模下能够应用的技术包含: 采纳CDN(content delivery network)形式,使动态内容更贴近用户,升高网络时延。应用具备健康检查和主动伸缩性能的负载均衡器,依据负载动静调整服务器数量。应用一致性哈希或DHT(distributed hash table),依据哈希函数在服务器或数据库之间散布数据。应用速率限度或节流来管制每个用户或每个工夫距离的申请或操作数量。应用加密或哈希来爱护传输或静止的敏感数据。 在这种规模下,零碎变得更加简单,须要更多翻新和试验。次要挑战有: 实现零碎跨多个地区或区域的高可扩展性和可用性。优化系统资源的老本和效率。解决边缘状况和零碎行为或数据异样。在实在环境中测试和调试零碎。用户数量从100万扩大到1亿:现阶段的次要挑战是: 大规模保护零碎的高质量和可靠性。适应一直变动的用户需要和冀望。随着新技术和新趋势一直倒退。与市场上的其余零碎竞争。在这种规模下能够应用的一些技术包含: 应用天文复制或多区域部署,在不同地理位置复制或部署零碎,以进步性能和可用性。应用微服务或无服务器架构,将零碎合成为更小、独立和可扩大的性能单元。应用机器学习或异样检测,辨认并解决零碎或数据中的异样模式或事件。应用混沌工程或故障注入,模拟系统中的故障或中断,并测试其恢复能力。用户数量从1亿扩大到10亿: 在这种规模下,零碎变得十分先进和简单,必定须要更多的研发。 在这种规模下能够应用的一些技术包含: 应用自动化或调度工具来治理、部署和更新零碎,尽量减少人工干预。应用 A/B 测试或试验来测试和比拟实在用户应用零碎的不同版本或性能,并掂量其影响。应用大数据或数据分析来收集和解决大量数据,并生成见解和倡议。应用人工智能或深度学习来加强零碎性能和用户体验。服务发现和负载平衡机制。可能须要应用 Istio 或 Linkerd 等服务网格来治理微服务之间的通信和路由。服务网格能够提供服务发现、负载平衡、容错、平安和可察看性等性能。数据存储和缓存策略。可能须要应用 Couchbase 或 Cassandra 等分布式数据库来跨多个节点存储和查问数据。分布式数据库可提供可扩展性、可用性、一致性和性能等性能。可能还须要应用 Redis 或 Memcached 等分布式缓存来存储频繁拜访的数据,并缩小数据库负载。监控和日志记录工具。可能须要应用 Prometheus 或 Grafana 等监控工具来收集和可视化微服务的指标,如 CPU、内存、提早和吞吐量。可能还须要应用 Fluentd 或 Logstash 等日志工具来收集和剖析微服务的日志,如谬误、正告和事件。测试和部署工具。可能须要应用 JMeter 或 Gatling 等测试工具来模仿和测量微服务在不同负载状况下的性能。可能还须要应用 Jenkins 或 Spinnaker 等部署工具来主动协调微服务在不同环境中的部署。零碎和数据的安全性和可靠性。可能须要应用 Vault 或 Keycloak 等平安工具来治理微服务和用户的身份验证和受权。平安工具能够提供加密、令牌治理和身份联结等性能。可能还须要应用 Chaos Monkey 或 Gremlin 等可靠性工具来注入故障并测试微服务的弹性。可靠性工具能够帮忙辨认并修复零碎的潜在问题和破绽。零碎与微服务的集成和通信。可能须要应用 Kafka 或 RabbitMQ 等集成工具来实现微服务之间的异步和事件驱动通信。集成工具能够提供可扩展性、耐用性和容错等性能。可能还须要应用 gRPC 或 GraphQL 等通信工具来实现微服务与客户端之间高效灵便的通信。通信工具能够提供性能、互操作性和模式验证等性能。论断本文探讨了将分布式系统从1千用户扩大到10亿用户所波及的罕用技术和衡量,还针对每种规模提供了分步阐明。扩大分布式系统不是一个放之四海而皆准的问题,而是一直学习、调整和改良的过程。心愿这篇文章能为读者提供有用的见解和技巧,帮忙读者设计和扩大本人的分布式系统。 ...

February 28, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十五之垃圾收集器上篇

不同场景能够应用不同的垃圾收集器来进行GC,不同的垃圾收集器有不同的特点,有的单线程执行适宜单核、有的多线程并发执行、有的谋求高吞吐量、有的谋求低提早... 在学习垃圾收集器前须要学习肯定的前置常识如JVM运行时数据区、垃圾回收算法等,须要的同学能够查看该专栏下以前的文章,如 深入浅出JVM(二)之运行时数据区和内存溢出异样 深入浅出JVM(十二)之垃圾回收算法 深入浅出JVM(十三)之垃圾回收算法细节 垃圾收集器的内容细节都比拟多,文章将会分为上、中、下三篇 在上篇中次要介绍垃圾回收器的分类、性能指标以及串行与并行的垃圾收集器 在中篇中次要介绍并发的垃圾收集器以及并发执行带来的问题以及解决方案 在下篇中次要介绍低提早的垃圾收集器 GC分类与性能指标垃圾回收器分类依据GC线程数进行分类,能够分为单GC线程串行和多GC线程并行的垃圾回收器 单线程串行顾名思义就是单线程执行GC,多线程并行就是多个线程同时执行GC(须要多核) 依据GC工作模式进行分类,能够分为同一时刻GC线程独占式和用户、GC线程并发的垃圾回收器 GC线程独占式是GC线程执行时用户线程须要进展,而用户、GC线程并发式就是用户、GC线程并发执行 依据解决内存碎片进行分类,能够分为压缩式(无碎片内存)和非压缩式的垃圾回收器 依据解决内存区间进行分类,能够分为新生代、老年代的垃圾回收器 性能指标在介绍垃圾回收器前,须要理解两个性能指标:吞吐量和提早 在程序运行时,因为GC的存在,在进行GC时须要额定的开销,咱们心愿垃圾回收器可能有高吞吐量,尽早的实现GC,将运行工夫留给用户线程去解决咱们的程序 但因为种种原因可能导致GC的工夫过长,这样就会提早用户线程的执行,咱们总是心愿这种提早是低的 GC的指标尽量谋求高吞吐量和低提早 高吞吐量示意GC解决的快,低提早在交互程序中能给用户带来好的响应 然而高吞吐量和低提早是抵触的 以高吞吐量为优先,就要缩小GC频率,这样会导致GC须要更长的工夫,从而导致提早升高 以低提早为优先,为了升高每次GC暂停更短的工夫,只能增大GC频率,这样导致吞吐量升高 当初GC的指标是在高吞吐量优先的状况下尽量升高提早;在低提早优先的状况下尽量增大吞吐量 垃圾收集器以GC线程运行状态来分类,经典的垃圾收集器分为串行、并行、并发垃圾收集器,当初还有两款低提早垃圾收集器 串行垃圾收集器: Serial 、Serial Old 并行垃圾收集器: ParNew 、Parallel Scavenge , Parallel Old 并发垃圾收集器: G1 、CMS 低提早垃圾收集器: ZGC、 Shenandoah 垃圾收集器可能只解决年老代(新生代)或老年代,也可能对内存区域都进行解决 因为垃圾收集器可能只解决局部空间,因而要做到Full GC时,须要搭配其余垃圾收集器一起进行GC 比方Serial GC与Serial Old GC(图中黑线) 图中位于红色局部是解决年老代的垃圾收集器,位于灰色局部是解决老年代的垃圾收集器,其中G1都会解决 垃圾收集器之间会进行搭配应用,但在高版本中可能移除这种搭配关系,也可能移除垃圾收集器 串行垃圾收集器串行垃圾收集器次要有两种,别离解决年老代与老年代,它们相互搭配应用 Serial收集器应用复制算法解决年老代 Serial Old收集器应用标记-整顿算法解决老年代 (新生代)Serial收集器 + (老年代)Serial Old 收集器 运行图 串行收集器(单线程),简略高效(在单线程中)、内存开销最小 收集过程中,必须暂停其余所有用户线程,直到它收集完结 默认Client模式的收集器,适宜单核CPU 不适宜交互式 JVM参数设置-XX:+UseSerialGC :新生代应用Serial GC 老年代应用 Serial Old GC ...

February 28, 2024 · 1 min · jiezi

关于后端:DevOps自动化我用模板为编排提效100倍

模板是什么?看一个go template示例 echo "部署{{.svc}}服务"这个模板生成的shell执行后可打印部署**任意**服务,如: echo "部署user"echo "部署order"模板用于形容不变的流程,模板参数示意可变动的局部,模板参数最终由输出值代替。 模板的分类模板一共分三种:聚合模板、编排模板、执行模板组成,实质是雷同的文本在不同的阶段采纳不同模板渲染规定。 聚合模板聚合本地模板文件到一个编排内,性能相似helm。 左右分隔符别离为%{和}%,尽量和支流分隔符辨别开。 下图为聚合argo workflow templates、执行模板、配置模板到一份编排示例: 模块定义模板用来定义代码、kube、测试等模块的属性(含平安规定)、执行脚本、脚本配置模板。 模块的次要定义内容如下图: 以下为模块定义的一些示例 模板的左右分隔符别离为!{和}!。代码code.common定义示例如下: code: common: labels: role: website,iot # role:代码仓库所属角色 package: true # 示意公共库 config: "" # 示意不须要构建镜像 settings: repo: http://xxxxxx/common.git mvn: api: # 只上传jar包 不打包和构建镜像 dir: "" sonar: exclusions: 'src/main/java/xxx/protobuf/**' # sonar扫描排除pb代码像默认属性、平安规定、执行脚本、配置文件在整个模块都是类似的,因而优先定义在独立的全局配置。code: # 模块名 __global__: # 模块的全局配置 workflow: templates: | %{readText "code/argo.templates.yaml" | indent 36}% security: pom: - name: "fastjson反序列化破绽" env: ".*" action: "Info" content: "com\\.alibaba:fastjson:jar:1\\.2\\.(([1-7][0-9]?)|(8[0-2])):compile" message: "低版本fastjson存在反序列化安全漏洞,请降级到最新版本1.2.83及以上版本!" execTmpl: | %{readText "code/argo.yaml" | indent 34}% config: - | %{readText "code/run.Dockerfile" | indent 34}% default: type: git template: public/java:latest !{- if contains (or $.engine.metadata.annotations.codes "") "common" }! depends: - common !{- end }!定义中不同环境的雷同属性的值不一样。 ...

February 28, 2024 · 3 min · jiezi

关于后端:DevOps自动化我的云解决方案

<font style="color:red;">内容导读:</font>[toc] 为什么要用云自动化计划?根因是解决单主问题,自动化是DevOps落地的基石,平台必须要思考大规模场景问题,传统的Jenkins存在单主问题,而云原生的主节点可弹性伸缩的。 用云原生还能很好的解决资源管理、多仓库依赖构建、多服务依赖公布等问题,同时扩展性良好,易保护。 我是怎么实现的?基础架构基础架构是编排+DAG(云原生)+插件。 DAG(云原生)有向无环图,无效管制工作执行的程序和依赖。 业界开源的次要有两款产品:argo Workflow和tekton。 目前采纳argo Workflow落地,因为它一切都是模板,概念简略,功能强大且灵便。编排编排是对计算机系统、利用及服务的自动化配置、治理和协调,编排能够更轻松地治理简单工作和工作流。 上面为一个简略工作的编排示例 kind: EngineapiVersion: api/v1metadata: name: demo # 指定工作名称 namespace: ops-mz830 # 指定运行命名空间,按我的项目划分 envs: # 同时部署开发和测试环境 - dev - sit labels: # 为工作打标签 app: demo annotations: title: '测试devops性能(不影响服务)'spec: global: # 全局配置,次要配置工作流和k8s workflow: templates: - name: whalesay # 定义执行工作的模板:测试用 打印消息 性能相似shell echo ${msg} inputs: parameters: - name: msg container: image: docker/whalesay command: [ cowsay ] args: [ "{{inputs.parameters.msg}}" ] oneStep: # 定义执行的工作:oneStep(一步工作,优化展现成果和性能,实用于简略工作),stages(多阶段工作,实用于简单工作场景) exec: - name: pull-code template: whalesay arguments: parameters: - name: msg value: '下载代码' - name: compile-api template: whalesay arguments: parameters: - name: msg value: '编译api' depends: [ pull-code ] # 需等 `pull-code`执行完结再执行compile-api工作流 ...

February 28, 2024 · 3 min · jiezi

关于后端:深入理解-Java-修饰符与封装访问权限行为控制与数据隐藏

Java 修饰符Java 修饰符 用于管制类、属性、办法和构造函数的拜访权限和行为。它们能够分为两组: 拜访修饰符:public: 意味着代码对所有类可拜访。private: 意味着代码只能在申明的类外部拜访。default: 意味着代码只能在同一包中拜访。protected: 意味着代码在同一包和子类中可拜访。非拜访修饰符:final: 意味着类不能被继承,属性和办法不能被重写。static: 意味着属性和办法属于类,而不属于对象。abstract: 意味着类不能用于创建对象,办法没有主体,必须由子类提供。transient: 意味着在序列化蕴含它们的对象时,属性和办法将被跳过。synchronized: 意味着办法一次只能由一个线程拜访。volatile: 意味着属性的值不会在本地线程缓存,总是从“主内存”读取。示例: 拜访修饰符: // public类能够被任何类拜访public class Main { // private属性只能在 Main 类外部拜访 private int x = 10; // default办法只能在同一个包中拜访 void myMethod() { System.out.println("This is a default method."); } // protected办法能够在同一个包和子类中拜访 protected void myProtectedMethod() { System.out.println("This is a protected method."); } public static void main(String[] args) { Main myObj = new Main(); System.out.println(myObj.x); // 谬误,无法访问公有属性 myObj.myMethod(); // 能够拜访 default 办法 myObj.myProtectedMethod(); // 能够拜访 protected 办法 }}非拜访修饰符: ...

February 27, 2024 · 2 min · jiezi

关于后端:smartdoc-302发布生成的word格式接口文档遥遥领先

smart-doc 是一款同时反对 JAVA REST API 和 Apache Dubbo RPC 接口文档生成的工具,smart-doc 利用接口泛型和 javadoc 正文主动剖析生成 api 接口文档,不采纳任何注解侵入到业务代码中。只须要在我的项目中引入 smart-doc 提供的 maven 或者是 gradle 插件,而后依照标准写好 javadoc 正文即可生成 api 文档。同时 smart-doc 也反对生成 openapi 和 postman 这些标准的文档,生成后能够间接导入相干工具做测试。 目前在国内已被小米、科大讯飞、同程旅行、快手、马蜂窝、顺丰等出名公司所应用。 仓库地址https://github.com/TongchengOpenSource/smart-doc 重要更新内容反对分批上传文档到 torna#697反对提取 java record 的正文#703重构优化 word 模版,也是行业内首次在 word上实现了markdown原样的文档,生成的文档更丑陋 #710反对 @JsonSerialize(using = ToStringSerializer.class)字段类型的解决。 #715优化常量获取,兼容更多用户能够在门路中应用各种常量。#730本次社区共计合并的 pr 20+,修复了多个bug, 更多更新内容请查看 https://github.com/TongchengOpenSource/smart-doc/releases/tag/3.0.2 新增贡献者@bugDesigner1@WingGao@SteinsGate1097302@linwumingshi@Mr-lijx@LabelZhou@baboy本次更新新增7位新的社区贡献者,新增人数为smart-doc社区历史之最。非常感谢下面的几位贡献者踊跃的参加社区奉献。为社区的倒退起到了十分踊跃的作用。 社区奉献smart-doc 作为同程旅行的大力支持开源我的项目,对于社区奉献的 committer ,咱们将提供书籍、文化衫等礼品作为处分,十分激励社区用户参加共建。后续社区也会逐渐减少其余语言的反对。 将来打算新增对websocket的反对。新增GRPC反对

February 27, 2024 · 1 min · jiezi

关于后端:MANG6346风险业务分析

Business Analytics and Risk This assessment relates to the following module learning outcomes: A. Knowledge and Understanding A1, A2, A3 B. Subject Specific Intellectual and Research Skills B2, B3. C. Transferable and Generic Skills C1, C3, C4 Coursework Brief: Your assignment is based on the case Deng, Yuming, Xinhui Zhang, Tong Wang, Lin Wang, Yidong Zhang, Xiaoqing Wang, Su Zhao, Yunwei Qi, Guangyao Yang, and Xuezheng Peng. "Alibaba realizes millions in cost savings through integrated demand forecasting, inventory management, price optimization, and product recommendations." INFORMS Journal on Applied Analytics 53, no. 1 (2023): 32-46.. ...

February 27, 2024 · 3 min · jiezi

关于后端:mybatis-selectKey-赋值未生效为什么

Statement配置如下: <insert id="insertStatemnet" parameterType="User"> insert into user ( user_name ) values (#{user#userName}) <selectKey resultType="long" order="AFTER" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> </insert>Dao 层代码如下public interface UserMapper{ int insert(@Param(user) User user);}class User{ long id; String userName; ...getter/setter}User user = userMapper.insert(user);user.getId() 获取的后果等于0应用Mybatis Insert User表,应用selectKey获取LAST_INSERT_ID() ,赋值给user的id属性,发现id属性值未被set进去,user.getId() 获取的后果等于0,会话的LAST_INSERT_ID() 曾经到远远超过0了,返回0显著是不对的。 对于LAST_INSERT_ID() 能够参考 LAST_INSERT_ID 文章。 开始探索为什么?属性值获取到的是0,要么是SELECT LAST_INSERT_ID() sql未执行,应用了id long类型的默认值0,要么是执行了但获取到的值是0,或者是Mybatis set对象id属性值的时候没set进去。 Mybatis应用SelectKeyGenerator解决selectKey标签,从这里开始动手 private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) { try { if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) { String[] keyProperties = keyStatement.getKeyProperties(); final Configuration configuration = ms.getConfiguration(); final MetaObject metaParam = configuration.newMetaObject(parameter); if (keyProperties != null) { Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE); List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); if (values.size() == 0) { throw new ExecutorException("SelectKey returned no data."); } else if (values.size() > 1) { throw new ExecutorException("SelectKey returned more than one value."); } else { MetaObject metaResult = configuration.newMetaObject(values.get(0)); ... setValue(metaParam, keyProperties[0], values.get(0)); .... } } } } catch (ExecutorException e) { throw e; } catch (Exception e) { throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e); } }验证发现keyExecutor.query获取到的values是[100],阐明SELECT LAST_INSERT_ID() 查问没问题,那问题必然呈现在上面的setValue办法外面。 ...

February 27, 2024 · 2 min · jiezi

关于后端:Mybatis-入门介绍

MyBatisMyBatis是一个一流的长久化框架,反对自定义SQL、存储过程和高级映射。 MyBatis简直打消了所有的JDBC代码,手动设置参数和检索后果的步骤。 MyBatis能够应用简略的XML或注解进行配置,将根本类型、Map接口和Java POJO(一般的Java对象)映射到数据库记录。 mybatis mybatis doc tools 简略介绍MyBatis(原名为iBatis)是一款Java长久层框架,它提供了一种简略而灵便的形式来拜访数据库。 MyBatis的指标是通过打消冗余的JDBC代码,使开发人员可能更专一于SQL语句和后果映射。 以下是一些要害的特点和概念,帮忙你更好地了解MyBatis: SQL映射:MyBatis应用XML或注解形式将SQL语句与Java办法进行映射。在XML文件中,你能够编写SQL语句,并指定参数和后果的映射关系。参数映射:MyBatis反对多种参数映射形式,包含地位参数、命名参数和自定义类型处理器。这使得你能够灵便地将Java对象作为参数传递给SQL语句。后果映射:MyBatis能够将SQL查问的后果映射为Java对象。你能够定义映射规定,将查问后果中的列与Java对象的属性进行对应。动静SQL:MyBatis提供了弱小的动静SQL性能,能够依据条件来动静地生成SQL语句。你能够应用条件判断、循环和片段等性能来构建灵便的SQL语句。事务反对:MyBatis能够治理数据库事务,你能够通过配置文件或编程形式来管制事务的提交和回滚。插件机制:MyBatis提供了插件机制,能够通过自定义插件来扩大框架的性能。你能够在SQL语句执行前后进行拦挡和批改,实现日志记录、性能监控等性能。应用MyBatis的流程通常包含以下步骤: 配置数据源:在配置文件中指定数据库连贯信息,包含数据库类型、URL、用户名和明码等。定义SQL映射:应用XML文件或注解形式定义SQL语句和参数、后果的映射关系。编写Java代码:编写Java代码,调用MyBatis提供的API来执行SQL语句。你能够应用会话(SqlSession)来执行增删改查操作。执行SQL语句:通过调用相应的办法来执行SQL语句,并获取后果。MyBatis是一款功能强大而灵便的长久层框架,它可能无效地简化数据库拜访的开发工作。 它曾经在许多Java我的项目中失去广泛应用,成为了Java开发人员的首选之一。 mybatis 与 hibernate 的比照表格上面是MyBatis和Hibernate的比照表格,以便更好地了解它们之间的区别: 个性MyBatisHibernate数据库反对反对多种关系型数据库反对多种关系型数据库SQL管制提供灵便的SQL管制,开发者手动编写和治理SQL语句主动创立和治理SQL语句,更面向对象的形式对象关系映射(ORM)较弱的ORM反对,须要手动解决对象和数据库表之间的映射关系弱小的ORM反对,主动解决对象和数据库表之间的映射关系存储过程和函数反对提供良好的存储过程和函数反对提供无限的存储过程和函数反对缓存机制提供一级缓存和二级缓存提供一级缓存和二级缓存查问性能查问性能较高,能够优化SQL语句查问性能较低,Hibernate会主动生成简单的查问语句灵活性更灵便,能够间接编写SQL语句较少灵便,须要依照Hibernate的标准进行操作学习曲线绝对较低,容易上手绝对较高,须要把握更多的概念和API须要留神的是,MyBatis和Hibernate都是优良的长久层框架,每个框架在不同的场景和需要下有其适用性。 MyBatis更适宜对SQL语句的管制要求较高的我的项目,而Hibernate则更适宜那些心愿通过ORM来简化数据拜访的我的项目。 Hello Worldmybatis.jar & mysql-connector-java.jar<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version></dependency>MyBatisUtil.javapublic class MyBatisUtil { private MyBatisUtil(){} private static SqlSessionFactory sqlSessionFactory = null; static { try { sqlSessionFactory = new SqlSessionFactoryBuilder().build( Resources.getResourceAsStream("mybatis-config.xml")); } catch (IOException e) { e.printStackTrace(); } } public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; }}mybatis-config.xml & jdbc.properties<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <!-- 引入配置信息文件 --> <properties resource="jdbc.properties" /> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${user}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/ryo/mapper/UserMapper.xml"/> </mappers></configuration>driver=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8user=rootpassword=UserMapper.java & UserMapper.xmlpublic interface UserMapper { User selectUser(Long id);}<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.ryo.mapper.UserMapper"> <!--定义所有列,方便使用,个别应该防止应用*--> <sql id="columns"> id,username,password,createdOn</sql> <!--id 对应办法名称--> <select id="selectUser" parameterType="java.lang.Long" resultType="com.ryo.domain.User"> SELECT <include refid="columns"/> FROM User WHERE id = #{id} </select></mapper>sql & domainCREATE TABLE user ( id BIGINT(20) PRIMARY KEY AUTO_INCREMENT NOT NULL COMMENT '主键, 自增', username VARCHAR(64) NOT NULL COMMENT '用户名', password VARCHAR(128) NOT NULL COMMENT '明码', createdOn DATETIME NOT NULL COMMENT '创立工夫', UNIQUE INDEX `username_UNIQUE` (`username`)) COMMENT '用户表';INSERT INTO `user` (username, password, createdOn) VALUES ( 'ryo', '123456', '2016-07-28 14:32:30');public class User implements Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; private String username; private String password; private Date createdOn; //getter & setter //toString()}UserMapperTest.java & resultpublic class UserMapperTest { private SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); @Test public void testSelectUser() throws IOException { UserMapper userMapper = sqlSessionFactory.openSession().getMapper(UserMapper.class); System.out.println(userMapper.selectUser(1L)); }}User{id=1, username='ryo', password='123456', createdOn=Thu Jul 28 14:32:30 CST 2016}Process finished with exit code 0本文由博客一文多发平台 OpenWrite 公布!

February 27, 2024 · 2 min · jiezi

关于后端:一文教会你如何利用火焰图快速定位内存泄漏

从 greptimedb#1733 开始,GreptimeDB 应用 Jemalloc 作为默认的内存分配器,这不仅有助于晋升性能和升高内存碎片,也提供了便捷的内存剖析性能。在 记一次 Rust 内存透露排查之旅 | 经验总结篇 这篇文章中,咱们介绍了剖析 Rust 利用内存透露的几种罕用办法,而在本文中将具体介绍基于 Jemalloc 的排查伎俩。 当您在应用或者开发 GreptimeDB 的过程中,如果遇到内存使用量异样的问题,能够参照本篇文章疾速排查和定位可能存在的内存透露。 筹备工作装置必要工具装置 flamegraph.pl 脚本 curl -s https://raw.githubusercontent.com/brendangregg/FlameGraph/master/flamegraph.pl > ${HOME}/.local/bin/flamegraph.plchmod +x ${HOME}/.local/bin/flamegraph.plexport PATH=$PATH:${HOME}/.local/binflamegraph.pl 是由 Brendan Gregg 编写的用于可视化热点代码调用栈的一个 Perl 脚本。Brendan Gregg 是一位致力于零碎性能优化的专家,在此感激他开发并开源了包含 flamegraph.pl 在内的诸多工具。装置 jeprof 命令 # For Ubuntusudo apt install -y libjemalloc-dev# For Fedorasudo dnf install jemalloc-devel对于其余操作系统,您能够通过 pkgs.org 来查找 jeprof 的依赖包。启用 GreptimeDB 的内存剖析性能GreptimeDB 的内存剖析性能是一个默认敞开的个性,您能够通过在编译 GreptimeDB 时关上 mem-prof feature 来启用此性能。 cargo build --release -F mem-prof对于是否应该默认开启 mem-prof 个性,greptimedb#3166 正在进行探讨,您也能够留下您的认识。启动 GreptimeDB 并启用 mem-prof 性能为了启用内存剖析性能,在启动 GreptimeDB 过程时也须要设置环境变量MALLOC_CONF: ...

February 27, 2024 · 2 min · jiezi

关于后端:深入浅出JVM十四之内存溢出泄漏与引用

本篇文章将深入浅出的介绍Java中的内存溢出与内存透露并阐明强援用、软援用、弱援用、虚援用的特点与应用场景 援用在栈上的reference类型存储的数据代表某块内存地址,称reference为某内存、某对象的援用 实际上援用分为很多种,从强到弱分为:强援用 > 软援用 > 弱援用 > 虚援用 平时咱们应用的援用实际上是强援用,各种援用有本人的特点,下文将一一介绍 强援用就是Java中一般的对象,而软援用、弱援用、虚援用在JDK中定义的类别离是SoftReference、WeakReference、PhantomReference 下图是软援用、弱援用、虚援用、援用队列(搭配虚援用应用)之间的继承关系 内存溢出与内存透露为了更革除的形容援用之间的作用,首先须要介绍一下内存溢出和内存透露 当产生内存溢出时,示意JVM没有闲暇内存为新对象调配空间,抛出OutOfMemoryError(OOM) 当应用程序占用内存速度大于垃圾回收内存速度时就可能产生OOM 抛出OOM之前通常会进行Full GC,如果进行Full GC后仍旧内存不足才抛出OOM JVM参数-Xms10m -Xmx10m -XX:+PrintGCDetails 内存溢出可能产生的两种状况: 必须的资源的确很大,堆内存设置太小 (通过-Xmx来调整)<!----> 产生内存透露,创立大量对象,且生命周期长,不能被回收内存透露Memory Leak: 对象不会被程序用到了,然而不能回收它们 对象不再应用并且不能回收就会始终占用空间,大量对象产生内存透露可能产生内存溢出OOM 狭义内存透露:不正确的操作导致对象生命周期变长 单例中援用内部对象,当这个内部对象不必了,然而因为单例还援用着它导致内存透露一些须要敞开的资源未敞开导致内存透露强援用强援用是程序代码中普遍存在的援用赋值,比方List list = new ArrayList(); 只有强援用在可达性剖析算法中可达时,垃圾收集器就不会回收该对象,因而不当的应用强援用是造成Java内存透露的次要起因 软援用当内存短缺时不会回收软援用 只有当内存不足时,产生Full GC时才将软援用进行回收,如果回收后还没短缺内存则抛出OOM异样 JVM中针对不同的区域(年老代、老年代、元空间)有不同的GC形式,Full GC的回收区域为整个堆和元空间 软援用应用SoftReference 内存短缺状况下的软援用  public static void main(String[] args) {         int[] list = new int[10];         SoftReference listSoftReference = new SoftReference(list);  //[I@61bbe9ba         System.out.println(listSoftReference.get());    }内存不短缺状况下的软援用(JVM参数:-Xms5m -Xmx5m -XX:+PrintGCDetails) //-Xms5m -Xmx5m -XX:+PrintGCDetails public class SoftReferenceTest {     public static void main(String[] args) {         int[] list = new int[10];         SoftReference listSoftReference = new SoftReference(list);         list = null;          //[I@61bbe9ba         System.out.println(listSoftReference.get());          //模仿空间资源有余         try{             byte[] bytes = new byte[1024 * 1024 * 4];             System.gc();        }catch (Exception e){             e.printStackTrace();        }finally {             //null             System.out.println(listSoftReference.get());        }    } }弱援用无论内存是否足够,当产生GC时都会对弱援用进行回收 ...

February 27, 2024 · 4 min · jiezi

关于后端:分层架构最佳实践

分层架构是罕用的架构设计办法,本文探讨了分层架构的概念、劣势、最佳实际,并给出了在架构设计中罕用的命名约定。原文: Layered Architecture in Software Architecture: Concept, Benefits, and Best Practices 分层架构是软件开发中宽泛应用的结构化设计办法,该办法将零碎划分为不同的层,每个层都有特定用处并与其余层交互。本文将探讨分层架构的概念、长处以及施行的最佳实际。 分层架构以四个关键问题为领导:用户(who)、性能(what)、部署(where)和施行(how)。 用户(Who) —— 开发满足用户需要的产品或零碎。 客户互动 —— 踊跃与应用产品的客户或顾客接触。设计人员和开发人员须要收集需要、召开会议并征求反馈意见,以确保最终产品合乎客户的冀望和指标。确定用户角色 —— 用户角色是依据用户的职称、职责或特定规范调配给他们的预约义类别。定义界面 —— 界面是用户与零碎或产品之间的交互点。界面设计要思考信息架构、视觉设计、交互模式和可用性准则等因素。原型设计、线框设计和用户测试通常用于欠缺和验证界面设计。思考可用性 —— 易于应用。可用性测试包含工作、场景和实在用户,以评估产品的可用性。性能(What) —— 定义零碎的性能、特点和高级模块。 零碎性能 —— 定义零碎能做什么以及如何与环境互动以实现目标,概述了零碎的具体操作、输出、输入和限度。业务性能 —— 代表零碎的具体性能或特色,为用户提供价值。依据零碎的性质和复杂程度,能够是基本功能,也能够是高级操作。通常源于零碎性能,旨在满足特定的用户需要。业务性能通常作为零碎需要或规格的一部分记录在案,并作为开发和测试的根底。高级模块 —— 封装相干性能或个性,代表了可独立开发、部署和治理的内聚性能单元。部署(Where) —— 侧重于零碎的基础设施方面,波及利用网络工具和服务、设计网络基础设施、思考分布式网络架构、利用基础设施即代码实际以及优化网络性能。 Azure 网络架构 —— Microsoft Azure 提供各种网络工具和服务,如 Azure 虚构网络、Azure 虚构广域网、Azure 专用链接和 Azure 防火墙,以反对工作负载和服务。谷歌云网络设计 —— 谷歌云提供虚构专用云(VPC)的应用、网络安全治理以及评估寰球或地区服务的利用需要。分布式网络架构 —— 为要害工作利用提供牢靠的根底,易于扩大,并能适应一直变动的利用和服务流。网络架构物理域 —— 网络架构正在一直倒退,以反对具备认知治理性能的高度自动化网络。这种转变波及动静适应性、云资源分配、联结数据管道和开放式 API,指标是优化性能、老本和业务敏捷性。基础设施即代码(IaC) —— 基础设施即代码(IaC)是一种 DevOps 实际,通过描述性模型治理基础设施,涵盖网络、计算服务、数据库、存储和连贯拓扑。施行 IaC 有很多益处,如加强部署信念、治理多个环境以及更好的理解基础架构状态。施行(How) —— 施行细节,包含架构模式和层与层之间的通信机制。 架构信息传递模式 —— 用于促成应用程序不同局部或不同零碎之间的信息替换,可分为信息替换架构和路由。 信息替换架构 —— 一个发送方和多个接管方之间采纳不同的办法或模式传输信息。 ...

February 27, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十三之垃圾回收算法细节

上篇文章深入浅出JVM(十二)之垃圾回收算法探讨了垃圾回收算法,为了可能更加充沛的了解后续的垃圾收集器,本篇文章将深入浅出解析垃圾回收算法的相干细节,如:STW、枚举根节点如何防止长时间STW、平安点与安全区、跨代援用引起的GC Root扫描范畴增大等问题 HotSpot垃圾回收算法细节STWStop The Word STW: GC中为了剖析垃圾过程确保一致性,会导致所有Java用户线程进展 可达性剖析算法枚举根节点导致STW 因为不停顿线程的话,在剖析垃圾的过程中援用会变动,这样剖析的后果会不精确 根节点枚举枚举GC Roots的过程是耗时的,因为要找到栈上的Reference作为根节点,这就不得不对整个栈进行扫描 为了防止枚举根节点消耗太多工夫,应用OopMap(Ordinary Object Pointer一般对象指针)数据结构来记录reference援用地位 根节点枚举必须暂停用户线程,因为要保障一致性的快照(根节点枚举是用户线程进展的重要起因) 如果单纯遍历GC Roots和援用链过程会十分的耗时,应用OopMap记录援用所在位置,扫描时不必去办法区全副扫描 应用OopMap疾速,精准的让HotSpot实现根节点枚举 平安点与平安区域safe point代码中援用的地位可能产生变动,每时每刻更新OopMap的开销是十分大的,因而规定在平安点地位才更新OopMap 那什么地位才是平安点呢? 平安点所在的地位个别具备让程序长时间执行的特色,比方办法调用、循环、异样跳转等 因为只有平安点地位的OopMap是无效的,因而在进行GC时用户线程须要停留在平安点 让用户线程到最近的平安点停下来的形式有两种,别离是领先式中断、主动式中断 领先式中断: 垃圾收集产生时,中断所有用户线程,如果有用户线程没在平安点上就复原它再让它执行会到平安点上 主动式中断: 设置一个标记位,当要产生垃圾回收时,就把这个标记位设置为真,用户线程执行时会被动轮询查看这个标记位,一旦发现它为真就去最近的平安点中断挂起 hotspot抉择主动式中断,应用内存保护陷阱形式将轮循标记位实现的只有一条汇编指令,高效 平安点设立太多会影响性能,设立太少可能会导致GC等待时间太长 平安点保障程序线程执行时,在不长时间内就可能进入垃圾收集过程的平安点 safe region平安点只能保障程序线程执行时,在不长时间内进入平安点,如果是Sleep或者Blocking的线程呢? 平安区域:确保某一段代码中,援用关系不发生变化,这段区域中任意中央开始垃圾收集都是平安的 sleep、blocking线程须要停留在安全区能力进行GC 用户线程执行到安全区,会标识本人进入安全区,垃圾回收时就不会去管这些标识进入安全区的线程 用户线程要来到安全区时,会去查看是否执行完根节点枚举,执行完了就能够来到,没执行完就期待,直到收到能够来到的信号(枚举完GC Roots) 记忆集与卡表后面说到过分代收集的概念,比方GC可能是只针对年老代的,但年老代对象可能援用老年代,对了可达性剖析的正确性可能要将老年代也退出GC Roots的扫描范畴中,这无疑又减少了一笔开销 上述问题叫做跨代援用问题,跨代援用问题不仅仅只存在与年老代与老年大中,相熟G1、低提早ZGC、Shenandoah收集器的同学会晓得它们分区region也会存在这种跨代援用 应用记忆集来记录存在跨代援用的状况,当产生跨代援用时只须要将一部分跨代援用的退出GC Roots的扫描范畴,而不必全副扫描 能够把记忆集看成记录从非收集区指向收集区的指针汇合 罕用卡表实现记忆集的卡精度(每个记录准确到内存区,该区域有对象有跨代指针) 卡表简略模式是一个字节数组,数组中每个元素对应着其标识内存区域中一块特定大小的内存区(这块内存区叫:卡页) 如果卡页上有对象含有跨代指针,就把对应卡表数组值改为1(卡表变脏),1阐明卡表对应的内存块有跨代指针,把卡表数组上元素为1的内存块退出GC Roots中一起扫描(图中卡表绿色地位示意卡表变脏存在跨代援用) 记忆集解决跨代援用问题,缩减GC Roots扫描范畴 写屏障保护卡表变脏应该放在跨代援用赋值之后,应用写屏障来在跨代援用赋值操作后进行更新卡表 这里的写屏障能够了解为AOP,在赋值实现后进行更新卡表的状态 更新卡表操作产生额定的开销,在高并发状况下还可能产生伪共享问题,升高性能 能够不采纳无条件的写屏障,先查看卡表标记,只有未被标记过期才将其标记为变脏,来防止伪共享问题,但会减少额定判断的开销 -XX:+UseCondCardMark 是否开启卡表更新条件判断,开启减少额定判断的开销,能够防止伪共享问题 总结本篇文章围绕垃圾回收算法细节深入浅出解析STW、根节点枚举防止长时间STW、安全区与平安区域、记忆集解决跨代援用增大GC Root扫描范畴、保护卡表的写屏障等 为了防止用户线程扭转援用关系,可能正确的进行可达性剖析,须要stop the word 进行用户线程 枚举GC Roots时为了防止长时间的STW,应用OopMap记录援用地位,防止扫描办法区 因为援用关系的变动,实时更新保护OopMap的开销是很大的,只有在循环、异样跳转、办法调用地位的平安点才更新OopMap,因而只有在平安点中能力正确的进行GC 安全区能够看成扩大的平安点,在一块代码中不会扭转援用关系;对于sleep、blocking状态的用户线程来说,只须要在安全区就可能进行GC hotspot采纳主动轮循式中断,用户线程运行时主动轮循判断是否须要进行GC,须要进行GC则到左近最近的平安点/区,GC时不会治理这些进入安全区的用户线程,当用户线程要来到安全区时查看是否枚举完GC Root,枚举完则能够来到否则期待 ...

February 27, 2024 · 1 min · jiezi

关于后端:Git-教程解密-gitignore-文件合并分支解决冲突及-Git-帮助

Git 帮忙如果你遗记了命令或命令的选项,你能够应用 Git 帮忙。 在命令行中,有几种不同的应用帮忙命令的形式: git command -help - 查看特定命令的所有可用选项git help --all - 查看所有可能的命令让咱们看看不同的命令。 Git -help 查看特定命令的选项任何时候,如果你须要帮忙来记住特定命令的选项,你能够应用 git command -help: 这将显示特定命令的所有可用选项: usage: git commit [] [--] ... -q, --quiet suppress summary after successful commit -v, --verbose show diff in commit message templateCommit message options -F, --file read message from file --author override author for commit --date override date for commit -m, --message commit message -c, --reedit-message reuse and edit message from specified commit -C, --reuse-message reuse message from specified commit --fixup use autosquash formatted message to fixup specified commit --squash use autosquash formatted message to squash specified commit --reset-author the commit is authored by me now (used with -C/-c/--amend) -s, --signoff add a Signed-off-by trailer -t, --template use specified template file -e, --edit force edit of commit --cleanup how to strip spaces and #comments from message --status include status in commit message template -S, --gpg-sign[=] GPG sign commitCommit contents options -a, --all commit all changed files -i, --include add specified files to index for commit --interactive interactively add files -p, --patch interactively add changes -o, --only commit only specified files -n, --no-verify bypass pre-commit and commit-msg hooks --dry-run show what would be committed --short show status concisely --branch show branch information --ahead-behind compute full ahead/behind values --porcelain machine-readable output --long show status in long format (default) -z, --null terminate entries with NUL --amend amend previous commit --no-post-rewrite bypass post-rewrite hook -u, --untracked-files[=] show untracked files, optional modes: all, normal, no. (Default: all) --pathspec-from-file read pathspec from file --pathspec-file-nul with --pathspec-from-file, pathspec elements are separated with NUL characterNote: You can also use --help instead of -help to open the relevant Git manual pageGit help --all 查看所有可能的命令要列出所有可能的命令,能够应用 help --all 命令: ...

February 26, 2024 · 3 min · jiezi

关于后端:32555-Fundamentals-of-Software-Development

32555 Fundamentals of Software Development Course area UTS: Information Technology Delivery Autumn 2024; City Credit points 6cp Requisite(s) 120 Credit Points in spk(s): C10061 Bachelor of Engineering Diploma in Engineering Practice OR 120 Credit Points in spk(s): C10066 Bachelor of Engineering Science OR 120 Credit Points in spk(s): C10067 Bachelor of Engineering OR 120 Credit Points in spk(s): C09067 Bachelor of Engineering (Honours) Diploma in Professional Engineering Practice OR 120 Credit Points in spk(s): C09066 Bachelor of Engineering (Honours) ...

February 26, 2024 · 10 min · jiezi

关于后端:COMP6236-Buffer-Overflow-Attacks

COMP6236 2024 Coursework 1: Buffer Overflow Attacks and Software Hijacking This coursework is divided into two parts. Part one is on buffer overflow attacks, which are based on Buffer Overflow Lab. You will be assessed on your ability to successfully exploit buffer overflows and other vulnerabilities and explain your methodology. Part two is on software hijacking, based on Reverse Engineering Lab and will assess your ability to carry out the successful exploitation of software. The coursework is an individual coursework and is worth 30% of the module marking in total. ...

February 26, 2024 · 10 min · jiezi

关于后端:COMP3211-问题求解

COMP3211 2023-24 Fall Semester Assignment #1 Date assigned: Wednesday, Feb 14, 2024 Due time: 23:59pm on Sunday, Feb 25, 2024 How to submit it: Submit your written answers as a pdf file on canvas.ust.hk. Submit your code for the last three programming questions as a zip file named YourStudentID.zip Penalties on late papers: 20% off each day (anytime after the due time is considered late by one day) Problem 1. (10%) Consider a 10x10 grid without any obstacles, and a robot with the same specification as our boundary following robot: eight sensors and four actions. Design a reactive production system to control the robot to go to one of the four corners, wherever its initial position is. Write a production system just for this task without calling the boundary following production system in the lecture note. ...

February 26, 2024 · 7 min · jiezi

关于后端:SQL-也能搞复杂时序查询使用-SQL-在-GreptimeDB-上做-Range-查询

查问并聚合一个「给定长度的工夫范畴的数据」,是时序数据中常见的一种查问模式。例如 PromQL 中的 Range selector,就原生地反对了这种时序查问。但对于通用的数据库查询语言 SQL ,这类时序查问很难通过原生的 SQL 实现,所以咱们在 GreptimeDB 中引入了扩大的 SQL Range 查问语法,将时序查问能力与 SQL 高度灵便的表达能力相结合,实现了 SQL 对时序数据查问的原生反对。 ✨ 让数据动起来!应用 SQL 在 GreptimeDB 上实现动静 Range 查问https://greptime.cn/playground 点击链接退出咱们的 Playground,立刻体验示例咱们用一个例子来介绍 Range 查问。上面这张表 temperature 记录了不同城市在不同工夫的气温: 咱们想查问北京从 2023 年 5 月 2 日(工夫戳为 1682985600000 )以前的: 每日的日平均气温;每日的周平均气温;如果某天的数据点缺失,则以前后两天平均气温均值作为这天的平均气温。咱们首先从 PromQL 的视角来看如何去写这句查问,对于两条查问,都须要以天为步长进行查问。对于日平均气温,须要向前聚合一天的数据,对于周平均气温,须要每次向前聚合一周的数据,并求出平均值。另外咱们须要应用 @ 将查问工夫对齐到工夫戳 1682985600000。 最初的查问为: -- 日平均气温avg_over_time(temperature{city="beijing"}[1d] @ 1682985600000) step=1d-- 周平均气温avg_over_time(temperature{city="beijing"}[7d] @ 1682985600000) step=1d但下面的查问存在一些问题。PromQL 强调的是做数据的查问,但不能很好地解决查问中缺失数据点的状况,也就是如何对查问的数据作平滑。PromQL 只是存在 Lookback delta 的机制(具体见:https://promlabs.com/blog/2020/07/02/selecting-data-in-promql...),用一些旧的数据来代替缺失的数据点。这样的默认行为在某些状况下并不是用户想要的。因为 Lookback delta 的机制的存在,会导致聚合的数据携带一些旧值。在默认状况下,PromQL 很难做到数据精确性的管制。并且针对咱们下面提出的数据平滑要求,PromQL 也没有很好的方法实现。 ...

February 26, 2024 · 2 min · jiezi

关于后端:Solo-开发者周刊-第5期打破常规探索技术新边界

这里会整合 Solo 社区每周推广内容、产品模块或流动投稿,每周五公布。在这期周刊中,咱们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的教训和见解。本杂志开源,欢送投稿。 产品举荐1. 新一代的团队合作平台-TeamlinkerTeamlinker是一个集成了不同性能和模块的团队合作平台。你能够分割你的团队成员,调配你的工作,开始一个会议,安顿各项事务,治理你的文件等。并且反对线下收费部署,性能和线上版本统一。(ansun投稿) 2. 「悬浮捷径SoftCircle」安卓平台的hao123,一键关上万物很多利用都会反对 Widget 插件,这能够让咱们无需关上利用,就实现一些操作,比方切歌,看天气等。「悬浮捷径」能够让这件事效率变得更高,咱们能够把任意 Widget 桌面插件增加进来,一件关上。(SoftCircle 投稿) 3. Pictode:十分钟DIY图形编辑器很轻松到目前为止,Pictode集成了泛滥实用功能,如工具切换、属性编辑、右键菜单、本地保留、导出图片、画布缩放、画布拖拽、历史记录、语言切换、主题切换等。(JessYang投稿) 4. 闪记词典APP——主打天然拼读语音的背单词软件,疾速记住英语单词闪记词典APP(开发中,半个月左右上线),主打天然拼读法背单词,是合肥梦幻时空科技有限公司旗下产品。咱们有华为背景的安卓工程师,和大厂UI设计师,前蚂蚁金服经营(墨尔本大学会计硕士)和多年教训的国企后端JAVA工程师。(sddzlsc投稿) 订阅这个专栏会同步更新在 Solo 社区、公众号、知乎、社群。 微信搜寻"Solo 独立开发者社区"或者扫描二维码,即可手机订阅。 社区网址:Solo 独立开发者社区-链接每一位独立开发者, 从 Solo 开始

February 26, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十二之垃圾回收算法

上篇文章深入浅出JVM(十一)之如何判断对象“已死”曾经深入浅出的解析JVM是如何评判对象不再应用,不再应用的对象将变成“垃圾”,期待回收 垃圾回收算法有多种,实用于不同的场景,不同的垃圾收集器应用不同的算法 本篇文章将围绕垃圾回收算法,深入浅出的解析垃圾回收分类以及各种垃圾回收算法 垃圾回收算法垃圾回收分类垃圾收集器有着多种GC形式,不同的GC形式有本人的特点,回收的堆内存局部也不同 堆内存分为新生代和老年代,新生代存储“年老”的对象,老年代存储“老”或内存大的对象,对象年龄由经验多少次GC来判断 其中整堆收集时不仅会回收整个堆还会回收元空间(间接内存) 局部收集(Partial GC): 收集指标是局部空间 新生代收集(Minor GC/ Young GC):收集新生代Eden、Survive to、Survive from区老年代收集(MajorGC/Old GC):收集老年代混合收集(Mixed GC):收集整个新生代和局部老年代整堆收集(Full GC): 整个堆 + 元空间标记-革除算法Mark-Sweep 标记:从GCRoots开始遍历援用链,标记所有可达对象 (在对象头中标记) 革除:从堆内存开始线性遍历,发现某个对象没被标记时对它进行回收 标记-革除算法实现简略、不须要扭转援用地址,然而须要两次遍历扫描效率不高,并且会呈现内存碎片 留神:这里的革除并不是真正意义上的回收内存,只是更新闲暇列表(标记这块内存地址为闲暇,后续有新对象须要应用就笼罩) 复制算法Copying Survive辨别为两块容量一样的Survive to区和Survive from区 每次GC将Eden区和Survive from区存活的对象放入Survive to区,此时Survive to区改名为Survive from区,原来的Survive from区改名为Survive to区 保障Survive to区总是闲暇的 如果Survive from区的对象通过肯定次数的GC后(默认15次),把它放入老年代 流程图留神:图中的dean为Eden区(写错) 留神:最终的survive from区存活对象占用的内存应该是(那两块蓝色)挨着一起的,图中为了标识字离开来了 复制算法不须要遍历,并且不会产生内存碎片,然而会节约survive区一半的内存,挪动对象时须要STW暂停用户线程,并且复制后会扭转援用地址(hotspot应用间接指针拜访,还要扭转栈中reference执行新援用地址) 如果复制算法中对象存活率太高会导致非常耗费资源,因而个别只有新生代才应用复制算法 标记-整顿算法Mark-Compact 标记:从GCRoots开始遍历援用链,标记所有可达对象(在对象头中标记) (与标记-革除算法统一) 整顿:让所有存活对象往内存空间一端挪动,而后间接清理掉边界以外的所有内存 标记-整顿算法不会呈现内存碎片也不会节约空间,然而效率低(比标记-革除还多了整顿性能),挪动对象导致STW和扭转reference指向 如果不挪动对象会产生内存碎片,内存碎片过多,将无奈为大对象分配内存 还有种办法:屡次标记-革除,等内存碎片多了再进行标记-整顿 分代收集算法 标记革除mark-sweep复制copying标记整顿mark-compact速度中快慢GC后是否须要挪动对象不挪动对象挪动对象挪动对象GC后是否存在内存碎片存在内存碎片不存在内存碎片不存在内存碎片须要挪动对象 意味着 要扭转改对象援用地址 也就是说要扭转栈中reference指向改对象的援用地址,并且会产生STW进展用户线程 当空间中存在大量内存碎片时,可能导致大对象无奈存储 分代收集算法 : 看待不同生命周期的对象能够采纳不同的回收算法(不同场景采纳不同算法) 年老代: 对象生命周期短、存活率低、回收频繁,采纳复制算法,高效 老年代: 对象生命周期长、存活率高、回收没年老代频繁,采纳标记-革除 或混用 标记-整顿 ...

February 26, 2024 · 1 min · jiezi

关于后端:PHP进阶Redis管道技术的实际运用

大家好,我是程序员若风,又到了技术分享时刻。 明天咱们来讲讲Redis管道技术 Redis管道技术介绍Redis流水线技术是一种通过同时收回多个命令来进步性能的技术,而无需期待对每个独自命令的响应。大多数Redis客户端都反对流水线操作。 -- 官网英文直译若风粗犷解释如果咱们同时有10个查问命令要执行,如果不借助管道技术,那么就是10次网络IO申请,借助管道技术,咱们能够将10条命令打包同时传输给Redis进行解决。并一次返回。这样网络IO由10次升高到了一次PHP理论应用Redis管道<?php// 连贯到 Redis 服务器$redis = new Redis();$redis->connect('127.0.0.1', 6379);// 创立 Pipeline 对象$pipe = $redis->pipeline();// 向 Pipeline 中增加多个命令$pipe->set('key1', 'value1');$pipe->set('key2', 'value2');$pipe->set('key3', 'value3');// 执行 Pipeline 中的命令$pipe->exec();在这个示例中,咱们首先通过 connect() 办法连贯到 Redis 服务器。而后,咱们应用 pipeline() 办法创立了一个 Pipeline 对象,接着向 Pipeline 中增加了多个 Redis 命令(这里是设置键值对的命令),最初应用 exec() 办法一次性执行 Pipeline 中的所有命令。这样,所有的命令会被打包发送给 Redis 服务器,在服务器端一次性执行,从而缩小了网络往返的工夫,进步了性能。 应用 Pipeline 技术时,须要留神以下几点: Pipeline 对象会在 exec() 办法被调用时才将所有命令发送到 Redis 服务器执行,因而要确保在增加完所有命令后再调用 exec() 办法。在 Pipeline 中的命令执行后,会返回一个蕴含每个命令执行后果的数组。Pipeline 能够用于一系列的 Redis 命令,然而它不反对事务(即不能应用 MULTI 和 EXEC 命令)。应用 Pipeline 技术能够无效缩小 Redis 操作的提早,特地是在须要执行大量 Redis 命令的场景下,能够显著进步性能。好了,明天的分享到此为止。 ...

February 26, 2024 · 1 min · jiezi

关于后端:iexcelexcel-读取和写入解决-excel-OOM-问题

我的项目简介IExcel 用于优雅地读取和写入 excel。 防止大 excel 呈现 oom,简洁而不简略。 个性一行代码搞定所有OO 的形式操作 excel,编程更加不便优雅。sax 模式读取,SXSS 模式写入。防止 excel 大文件 OOM。基于注解,编程更加灵便。设计简略,正文残缺。不便大家学习革新。可依据注解指定表头程序反对 excel 文件内容 bytes[] 内容获取,便于用户自定义操作。变更日志变更日志v0.0.9 次要变更Fixed @ExcelField注解生效问题 创作原因理论工作和学习中,apache poi 操作 excel 过于简单。 近期也看了一些其余的工具框架: easypoieasyexcelhutool-poi都或多或少难以满足本人的理论须要,于是就本人写了一个操作 excel 导出的工具。 实现:在阿里 easyexcel 的根底上进行封装,晋升应用的繁难度。 疾速开始环境要求jdk1.8+ maven 3.x 引入 jar应用 maven 治理。 <dependency> <groupId>com.github.houbb</groupId> <artifactId>iexcel</artifactId> <version>1.0.0</version></dependency>Excel 写入示例// 根本属性final String filePath = PathUtil.getAppTestResourcesPath()+"/excelHelper.xls";List<User> models = User.buildUserList();// 间接写入到文件ExcelHelper.write(filePath, models);其中: User.javapublic class User { private String name; private int age; //fluent getter/setter/toString()}buildUserList()构建对象列表办法如下: /** * 构建用户类表 * @return 用户列表 * @since 0.0.4 */public static List<User> buildUserList() { List<User> users = new ArrayList<>(); users.add(new User().name("hello").age(20)); users.add(new User().name("excel").age(19)); return users;}写入成果excel 内容生成为: ...

February 26, 2024 · 1 min · jiezi

关于后端:Aapche-POI-java-excel-操作工具包入门

POIApache POI - the Java API for Microsoft Documents poi quick-start Hello Worldjar<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <verison>${poi.version}</verison></dependency><dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <verison>${poi-ooxml.version}</verison></dependency>get first sheet/*** 获取Excel第一个Sheet* @param file excel文件* @param fileSuffix excel类型 xls/xlsx*/public static Sheet getFirstSheet(File file, String fileSuffix) throws IOException { InputStream stream = new FileInputStream(file); Workbook wb = null; if (fileSuffix.equals("xls")) { wb = new HSSFWorkbook(stream); } else if (fileSuffix.equals("xlsx")) { wb = new XSSFWorkbook(stream); } return wb.getSheetAt(0);}get cell value/*** 依据列类型,取得对应的String类型* @return 不存在/不反对的类型,则返回""*/public static String getCellValueStr(Cell cell, String dateFormatStr) { String cellValueStr = ""; if (null != cell) { Object cellValue = null; switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: cellValueStr = cell.getRichStringCellValue().getString(); break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { cellValue= cell.getDateCellValue(); SimpleDateFormat formatter = new SimpleDateFormat(dateFormatStr); cellValueStr = formatter.format(cellValue); } else { cellValue=cell.getNumericCellValue(); cellValueStr = String.valueOf(cellValue); } break; case Cell.CELL_TYPE_BOOLEAN: cellValue = cell.getBooleanCellValue(); cellValueStr = String.valueOf(cellValue); break; case Cell.CELL_TYPE_FORMULA: cellValue = cell.getCellFormula(); cellValueStr = String.valueOf(cellValue); break; default: System.out.println("不反对的excel单元格类型"); } } return cellValueStr;}get excel content --> CSV/*** 获取Excel工作区的文件内容 - 字符串模式* - 须要置换excel每列的数据(除了每行的完结)以外所有换行符 "\n"* - 所有CEll都视为String类型*/public static String getSheetContent(Sheet sheet, String charset) throws UnsupportedEncodingException { StringBuffer stringBuffer = new StringBuffer(); String dateTimeFormatStr = "yyyy-MM-dd HH:mm:ss"; String lineSeparator = System.getProperty("line.separator", "\n"); //换行符 for(Row row : sheet) { for(Cell cell : row) { cell.setCellType(Cell.CELL_TYPE_STRING); //全副以String类型读取 String cellStr = new String(getCellValueStr(cell, dateTimeFormatStr).getBytes(), charset); String trimCellStr = cellStr.replaceAll(lineSeparator, StringUtils.EMPTY); stringBuffer.append(trimCellStr).append(","); } //此行有内容 if(row.getFirstCellNum() != CommonConstant.INVALID_NUMBER) { stringBuffer.deleteCharAt(stringBuffer.lastIndexOf(",")); //最初一个“,” stringBuffer.append(lineSeparator); } } return stringBuffer.toString();}本文由博客一文多发平台 OpenWrite 公布!

February 26, 2024 · 2 min · jiezi

关于后端:麒麟OS操作系统国家队

这是ren_dong的第31篇原创1、中标软件中标软件:国产操作系统龙头中标软件有限公司成立于2003 年,是国产自主操作系统和办公软件产品提供商,领有国防、民用两方面的相干企业与产品资质,是平安操作系统旗舰企业。中标软件的次要产品:桌面及服务器操作系统“中标麒麟”、挪动终端操作系统“中标凌巧”以及OFFICE办公软件“中标普华”。中标麒麟操作系统已实现目前所有国产 CPU 的兼容适配,取得了飞腾、龙芯、兆芯、申威、海光、鲲鹏六款国产 CPU 的官网认证。中标麒麟操作系统系列产品以操作系统技术为外围,全面反对国内外支流凋谢硬件平台,笼罩服务器端、桌面端,已兼容适配了超过4000款的软件和硬件产品。中标麒麟操作系统在 2011-2021 年间断十年中国 Linux 市场占有率第一。 2、天津麒麟天津麒麟:公安、军工、超算畛域提供商天津麒麟信息技术有限公司成立于 2014 年,旗下领有服务器、桌面和嵌入式三大系列操作系统产品,以及河汉麒麟云、河汉麒麟集群软件等翻新产品河汉麒麟操作系统宽泛适配以飞腾为代表的国产 CPU 和以 X86、ARM 为代表的国内支流 CPU,先后通过公安部结构化爱护级(第四级)测评以及军方的军 B+级平安测评认证,具备国内当先的高安全性。河汉麒麟是 PK 体系的重要参与者。“PK 体系”是飞腾“Phytium 处理器”和河汉麒麟“Kylin 操作系统”的联合,具备齐全自主知识产权,从 2011 年倒退至今,曾经胜利利用于政府信息化、电力、金融、能源等多个行业畛域,作为 PK 体系的基石,河汉麒麟 OS 也在党政、国防、金融、电信、能源、交通、教育、医疗等行业取得广泛应用。河汉麒麟桌面操作系统 V10 反对提供相似 Win 7 格调的用户体验,在国产平台的功耗治理、内核锁及页拷贝、网络、VFS、NVME 等方面发展优化,大幅晋升了稳定性和性能。同时在生态方面集成麒麟系列自研利用和搜狗输入法、金山WPS等单干办公软件,兼容反对 2000 余款安卓利用,补全了 Linux 生态利用短缺的短板 在高性能计算方面,天河一号和天河二号均部署河汉麒麟操作系统,保障了千万亿次超级计算机稳固高速的运行; 3、麒麟OS麒麟 OS:目前国内最为成熟、利用范畴最广的国产操作系统麒麟 OS次要由中国软件旗下两家子公司中标软件(中标麒麟)和天津麒麟(河汉麒麟)开发,依据中国软件官网公众号数据,以后中标软件、天津麒麟两家企业在党政、国防办公等畛域占有国产操作系统90%以上的市场份额2019 年 12 月,中国软件布告整合中标软件和天津麒麟,天津麒麟以新增出资约 1.39 亿元换股收买中标软件全副出资 2.5 亿元,换股比例为 1:1.8。2020 年 3 月 20 日,麒麟软件正式实现整合,中国软件仍为天津麒麟的控股股东,中标软件成为天津麒麟的全资子公司。 麒麟OS不仅在党政军畛域占据劣势,在金融、能源、交通、医疗等行业行业畛域也踊跃进行布局。 End码字不易,欢送关注、点赞,感激反对! 本文由mdnice多平台公布

February 26, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十一之如何判断对象已死

在办法中会创立大量的对象,对象并不一定是全局都会应用的,并且Java虚拟机的资源是无限的 当JVM(Java虚拟机)判断对象不再应用时,就会将其回收,防止占用资源 那么JVM是如何判断对象不再应用的呢? 本篇文章将围绕判断对象是否再应用,深入浅出的解析援用计数法、可达性剖析算法以及JVM如何判断对象是真正的“死亡”(不再应用) 判断对象已死援用计数算法援用计数算法判断对象已死在对象增加一个援用计数器,有中央援用此对象该援用计数器+1,援用生效时该援用计数器-1;当援用计数器为0时,阐明没有任何中央援用对象,对象能够被回收 然而该办法无奈解决循环援用(比方对象A的字段援用了对象B,对象B的字段援用了字段A,此时都将null赋值给对象A,B它们的援用计数器上都不为0,也就是示意对象还在被援用,但实际上曾经没有援用了) 长处 : 标记“垃圾”对象简略,高效毛病: 无奈解决循环援用,存储援用计数器的空间开销,更新援用记数的工夫开销因为无奈解决循环援用所以JVM不应用援用计数法 援用计数办法罕用在不存在循环援用的时候,比方Redis中应用援用计数,不存在循环援用 证实Java未采纳援用计数算法 public class ReferenceCountTest {     //占用内存     private static final byte[] MEMORY = new byte[1024 * 1024 * 2];      private ReferenceCountTest reference;      public static void main(String[] args) {         ReferenceCountTest a = new ReferenceCountTest();         ReferenceCountTest b = new ReferenceCountTest();         //循环援用         a.reference = b;         b.reference = a;          a = null;         b = null; //       System.gc();    } } ...

February 26, 2024 · 3 min · jiezi

关于后端:Cache-Design-in-PyRTL

Lab 7: Cache Design in PyRTL Assigned: Wednesday, February 21st, 2024 Due: Wednesday, February 28th, 2024 Points: 100 • MAY ONLY BE TURNED IN ON GRADESCOPE as PYTHON files (see below for details). • There is NO MAKEUP for missed assignments. • We strictly enforce the LATE POLICY for all assignments (see syllabus). Goals for This Lab By completing this lab, you should be able to utilize PyRTL to design and simulate a 4-way set-associative cache that follows a round-robin replacement policy. ...

February 26, 2024 · 6 min · jiezi

关于后端:来看大厂如何设计运营后台系统的

0 背景重经营的利用。对于App里的顶导航、我的页面、弹窗等,须要依据模式、版本、平台、语言、渠道等不同的维度进行经营治理。随着业务疾速倒退,版本疾速迭代,如何: 放弃经营资源可能被高效、稳固和灵便地配置高效稳固的为新的经营需要提供反对通过打造一个稳固、灵便、高效的经营配置平台来解决后面遇到的问题。本文次要分享咱们在建设高效的经营配置平台过程中积攒的一些教训以及面临的挑战和思考。 1 配置资源拆解经营类配置分类: 经营资源根底数据经营资源范例:弹窗根底数据:底部导航1.1 经营资源 经营资源可了解为App中常常变动的一些广告、经营流动等。比方上图中弹窗广告,就是一个典型的经营资源。 1.1.1 特色① 时效性强只在肯定工夫范畴内显示在C端固定地位。 ② 模式强相干每个流动、广告都只会呈现在固定的某些模式。 ③ 数据变动频繁特地是流动类数据,展现的图片文案等变动较为频繁 ④ 反对多语言展现基于公司海内站面向寰球用户的状况,不同模式需展现不同语言文案。 1.2 根底数据配置根底数据配置绝对于经营资源来说其变更的频率绝对较低,与工夫、版本的关系也没那么强。譬如上面爱奇艺海内App-底部导航栏(款式如上图)。 1.2.1 特色① 多维度须要针对不同的模式、语言做不同的配置。 ② 长期有效这种类型的配置个别长期存在,过期场景较少。 2 实际痛点面对接踵而至经营配置需要,最后实现不同的配置界面来对接各类经营产品需要。但这必然很大问题 2.1 经营效率低新经营配置需要,研发要开发对应配置页面,而后转给经营同学进行配置的治理,最初经营人员对资源进行配置上线,流程图: 每个经营配置需要都经需要评审、页面开发、配置管理、上线。配置页面开发,少则1到2天,问题就在: 研发老本高,每个需要要开发新的配置管理页面研发周期长,经营效率低,从需要的提出到经营上线周期长灵活性差,对不同的经营维度(模式、版本、工夫等)都须要当时确定好,无奈动静调整2.2 频繁反复开发通用型的经营配置后盾,某些特有性能特地对于前后端来说反复开发工作显著。如操作记录,审核机制,依据不同的模式版本语言过滤数据等性能,在每次呈现的配置需要中都需反复开发。 3 实际中的思考心愿设计一个通用解决方案,去解决上文论述的各种经营资源管理的问题。咱们把这个我的项目称为经营位。 调研确认 3.0 我的项目设计准则所有数据皆可配经营数据高可用接口性能高效一直实际和总结,抓手如下: 3.1 数据JSON化随业务迭代,无论采纳啥数据字段组成,都很难满足业务变动字段(题目、副标题、图片、跳转链接等)要求。对底层数据进行JSON化,对应数据字段即可实现可动静扩大,满足业务迭代需要。JSON化带来经营位字段治理问题,在经营后盾提供字段治理性能即可解决。 3.2 经营数据多点存储长久化存储,分布式缓存,以及接入业务方的本地缓存,经营数据的多方存储,保障极其状况都有降级数据获取,升高零碎异样损失。 3.3 接口SDK化经营数据,无论通过数据库的落地计划、还是分布式缓存,都无奈彻底解决服务中心化和服务抖动。通过接入的SDK化,实现数据的本地缓存更新机制,解除对中心化服务的依赖,晋升服务稳定性和性能。同时整个经营位服务变成可程度扩大,在扩大过程中也不会影响核心服务的稳定性。 调用方申请流程图 4 经营位架构经营位配置零碎整体框架图。从性能角度,大体上分为四层:数据层、服务层、接入层和监控层。 4.0 经营位架构图 4.1 数据层次要存储接入经营位的各类经营数据。 难点数据量大QPS高可通过redis集群做两头缓存,通过SDK使各业务方接入本地缓存、通过音讯监听异步更新,以解决核心服务的流量压力。 4.2 服务层服务层向下对底层数据进行操作;向上为接入层获取数据提供接入能力。提供四个服务能力: 经营后盾,面向经营人员和产品,提供数据的配置后盾开放平台,收归开发技术人员,提供一个减少经营位配置的后盾数据服务,次要是为调用数据的开发提供一个对立的、高可用的、高性能的api接口SDK,服务于数据服务,次要简化开发人员的接入老本,提供数据服务性能和可用性4.3 接入层4.3.1 C端接入咋不便?为简化开发接入老本,调用逻辑在SDK内实现,用户只需引入maven包,注入OppkitClient,封装OppkitRequest,通过OppkitClient间接调用即可返回过滤并且翻译后的数据。 4.3.2 B端配置咋更便捷?设计我的项目时,后盾配置的惟一准则:所有皆可配置。通过凋谢后盾来配置经营位,每个经营位相当于一个业务状态,如导航栏,而经营位蕴含多个数据,如title,link,title蕴含多种语言,需配置多语言key: 开放平台就是创立经营位,为经营位配置字段经营后盾,配置开放平台创立的经营位数据4.4 监控层除了数据存储层监控及烽火台对数据层与服务层的监控,还监控SDK内实现的本地缓存。 C端的接入即数据的获取在SDK外部实现,SDK外部实现性能: 若申请蕴含某些特定离散字段如设施id,因数据量极大,存入本地缓存会给业务方机器内存压力,则避开缓存间接申请服务为满足数据实时性要求较高业务方,新增不接入本地缓存的逻辑若只蕴含某些聚合度高字段如平台、版本、模式和语言等,则把申请的数据存入本地缓存。本地缓存通过监听经营平台的形式进行异步更新,当异步更新获取数据失败,则放弃之前的数据返回,防止极其状况经营数据全副为空,将业务损失降至最低SDK外部通过异步线程,将本地缓存应用状况通过定时线程存入,通过后盾界面展现各缓存应用状况,实时监控各类缓存应用5 稳定性与性能经营后盾稳定性与性能保障计划。 5.0 整体申请流程图 5.1 稳定性保障各类经营数据配置的经营后盾,稳定性很重要。 除了操作机制即经营流程化数据配置机制、多级数据存储应用分布式缓存及分布式数据库,还提供SDK计划来对服务故障进行降级。来看该计划落地过程。 5.2 SDK本地缓存计划实现本地缓存益处缓解核心服务的流量压力,更多流量申请到本地服务的内存基于海内站业务特点,国外网络环境不可预测,环境差,尽可能减少网络申请链路一旦核心服务故障,周知各业务方不要重新部署,以本地缓存实现数据降级本地缓存计划毛病显著一旦有经营后盾数据更新,各业务方无奈实时获取最新数据。对此,SDK开始迭代: ...

February 25, 2024 · 1 min · jiezi

关于后端:深入浅出JVM十之字节码指令下篇

上篇文章深入浅出JVM(九)之字节码指令(上篇)曾经深入浅出阐明加载存储、算术、类型转换的字节码指令,本篇文章作为字节码的指令的下篇,深入浅出的解析各种类型字节码指令,如:办法调用与返回、管制本义、异样解决、同步等 应用idea中的插件jclasslib查看编译后的字节码指令 办法调用与返回指令办法调用指令非虚办法: 静态方法,公有办法,父类中的办法,被final润饰的办法,实例结构器 与之对应不是非虚办法的就是虚办法了 一般调用指令 invokestatic: 调用静态方法invokespecial: 调用公有办法,父类中的办法,实例结构器<init>办法,final办法invokeinterface: 调用接口办法invokevirtual: 调用虚办法应用invokestatic和invokespecial指令的肯定是非虚办法 应用invokeinterface指令肯定是虚办法(因为接口办法须要具体的实现类去实现) 应用invokevirtual指令可能是虚办法 动静调用指令 invokedynamic: 动静解析出须要调用的办法再执行jdk 7 呈现invokedynamic,反对动静语言 测试虚办法代码父类 public class Father {     public static void staticMethod(){         System.out.println("father static method");    }      public final void finalMethod(){         System.out.println("father final method");    }      public Father() {         System.out.println("father init method");    }      public void overrideMethod(){         System.out.println("father override method");    } }接口 public interface TestInterfaceMethod {     void testInterfaceMethod(); }子类 public class Son extends Father{      public Son() {         //invokespecial 调用父类init 非虚办法         super();         //invokestatic 调用父类静态方法 非虚办法         staticMethod();         //invokespecial 调用子类公有办法 非凡的非虚办法         privateMethod();         //invokevirtual 调用子类的重写办法 虚办法         overrideMethod();         //invokespecial 调用父类办法 非虚办法         super.overrideMethod();         //invokespecial 调用父类final办法 非虚办法         super.finalMethod();         //invokedynamic 动静生成接口的实现类 动静调用         TestInterfaceMethod test = ()->{             System.out.println("testInterfaceMethod");        };         //invokeinterface 调用接口办法 虚办法         test.testInterfaceMethod();    }      @Override     public void overrideMethod(){         System.out.println("son override method");    }      private void privateMethod(){         System.out.println("son private method");    }      public static void main(String[] args) {         new Son();    } } ...

February 25, 2024 · 2 min · jiezi

关于后端:Raft-算法分布式-KV-面试汇总

本文选自《从零实现分布式 KV》课程的加餐文章。从零开始,手写基于 raft 的分布式 KV 零碎,课程详情能够看这里:https://av6huf2e1k.feishu.cn/docx/JCssdlgF4oRADcxxLqncPpRCn5b在简历上如何写这个我的项目?我的项目概述 基于 MIT 6824 课程 lab 框架,实现一个基于 raft 共识算法、高性能、可容错的分布式 KV 存储系统,保证系统的一致性和可靠性。 设计细节 设计基于 Raft 一致性算法的分布式系统架构。反对分布式数据存储和检索的 KV 存储引擎,采纳 Raft 协定确保数据的强一致性。实现数据分片和主动故障转移机制,以实现零碎的高可用性和容错性。应用 Go 语言编写,工程级代码可靠性和简洁性。后果 参照 Raft 论文应用 Golang 实现了领导选举、日志同步、宕机重启和日志压缩等次要性能。相熟 Raft 算法的基本原理和实现细节,相熟 Golang 并发编程和分布式调试。实现了一个高性能的分布式键值存储系统,保证数据的一致性和可靠性。通过所有代码测试,在负载测试中体现出良好的性能和稳定性,可能无效地应答并发拜访和故障状况。可能的面试问题&答复以下咱们每个节点统称为 Peer,面试官可能会叫节点、正本(Replica)、Node 等等术语,记得和面试官对齐就好。Raft 次要在什么场景中应用?通常有两种用处: 元信息服务,也称为配置服务(configuration services)、分布式协调服务(coordinator services)等等。如 etcd。用以追踪集群中元信息(比方正本地位等等)、多正本选主、告诉(Watch)等等。数据复制(Data replication)。如 TiKV、CockroachDB 和本课程中的 ShardKV,应用 Raft 作为数据复制和冗余的一种伎俩。与之绝对,GFS 应用简略的主从复制的办法来冗余数据,可用性和一致性都比 Raft 要差。注:在分布式系统中,数据指的是外界用户存在零碎中的数据;元数据指的是用户保护集群运行的外部信息,比方有哪些机器、哪些正本放在哪里等等。Raft 为了简洁性做了哪些就义(即有哪些性能问题)?每个操作都要落盘。如果想进步性能可能须要将多个操作 batch 起来。主从同步数据较慢。在每个 Leader 和 Follower 之间只容许有一个曾经收回 AppendEntries;只有收到确认了,Leader 能力发下一个。相似 TCP 中的“停等协定”。如果写入速度较大,可能将所有的 AppendEntries Pipeline 起来性能会好一些(即 Leader 不等收到上一个 AppendEntries 的 RPC Reply,就开始发下一个)只反对全量快照。如果状态机比拟小这种形式还能够承受,如果数据量较大,就得反对增量快照。全量快照同步代价大。如果快照数据量很大,每次全量发送代价会过高。尤其是如果 Follower 本地有一些较老的快照时,咱们只须要发增量局部即可。难以利用多核。因为 log 只有一个写入点,所有操作都得抢这一个写入点。Raft 在选举时是不能失常对外提供服务的,这在工程中影响大吗?不太大,因为只有网络故障、机器宕机等事件才会引起宕机。这些故障的发生率可能在数天到数月一次,但 Raft 选主在秒级就能实现。因而,在实践中,这通常不是一个问题。 ...

February 25, 2024 · 3 min · jiezi

关于后端:深入浅出JVM九之字节码指令上篇

本篇文章次要围绕字节码的指令,深入浅出的解析各种类型字节码指令,如:加载存储、算术、类型转换、对象创立与拜访、办法调用与返回、管制本义、异样解决、同步等 因为字节码指令品种太多,本文作为上篇概述加载存储、算术、类型转换的字节码指令 应用idea中的插件jclasslib查看编译后的字节码指令 字节码指令集大部分指令先以i(int)、l(long)、f(float)、d(double)、a(援用)结尾 其中byte、char、short、boolean在hotspot中都是转成int去执行(应用int类型的字节码指令) 字节码指令大抵分为: 加载与存储指令算术指令类型转换指令对象创立与拜访指令办法调用与返回指令操作数栈治理指令管制本义指令异样解决指令同步控制指令在hotspot中每个办法对应的一组字节码指令 这组字节码指令在该办法所对应的栈帧中的局部变量表和操作数栈上进行操作 字节码指令蕴含字节码操作指令 和 操作数 (操作数可能是在局部变量表上也可能在常量池中还可能就是常数) 加载与存储指令加载加载指令就是把操作数加载到操作数栈中(能够从局部变量表,常量池中加载到操作数栈) 局部变量表加载指令 i/l/f/d/aload 前面跟的操作数就是要去局部变量表的哪个槽取值iload_0: 去局部变量表0号槽取出int类型值常量加载指令 能够依据加载的常量范畴分为三种(从小到大) const < push < ldc存储存储指令就是将操作数栈顶元素出栈后,存储到局部变量表的某个槽中 存储指令 i/l/f/d/astore 前面跟的操作数就是要存到局部变量表的哪个槽istore_1:出栈栈顶int类型的元素保留到局部变量表的1号槽留神: 编译时就晓得了局部变量表应该有多少槽的地位 和 操作数栈的最大深度(为节俭空间,局部变量槽还会复用) 从常量池加载100存储到局部变量表1号槽,从常量池加载200存储到局部变量表2号槽(其中局部变量表0号槽存储this) 算术指令算术指令将操作数栈中的俩个栈顶元素出栈作运算再将运算后果入栈 应用的是后缀表达式(逆波兰表达式),比方 3 4 + => 3 + 4 留神当除数是0时会抛出ArithmeticException异样浮点数转整数向0取整浮点数计算精度失落Infinity 计算结果无穷大Nan 计算结果不确定计算值  public void test1() {         double d1 = 10 / 0.0;         //Infinity         System.out.println(d1);          double d2 = 0.0 / 0.0;         //NaN         System.out.println(d2);          //向0取整模式:浮点数转整数         //5         System.out.println((int) 5.9);         //-5         System.out.println((int) -5.9);           //向最靠近数舍入模式:浮点数运算         //0.060000000000000005         System.out.println(0.05+0.01);          //抛出ArithmeticException: / by zero异样         System.out.println(1/0);    }类型转换指令类型转换指令能够分为宽化类型转换和窄化类型转换(对应根本类型的非强制转换和强制转换) ...

February 25, 2024 · 2 min · jiezi

关于后端:Python笔记五之正则表达式

本文首发于公众号:Hunter后端 原文链接:Python笔记五之正则表达式 这一篇笔记介绍在 Python 里应用正则表达式。 正则表达式,Regular Expression,可用于在一个指标字符串里对于指定模式的字符进行查找、替换、宰割等操作。 比方,判断某个字符串里是否都是数字,或者是否蕴含指定字符串,又或者更间接的例子是判断电话号码或者邮箱是否非法等。 这一篇笔记里,咱们将先介绍一个正则表达式的函数,并以此来引入正则表达式的各种模式,并辅以各个例子进行介绍。 u1s1,正则表达式,我学了三四遍,学一遍忘一遍,忘一遍学一遍,只有隔一阵子不必就会忘,所以这一篇笔记力求将正则表达式的所有模式和用法都记录下来,用作之后的查找笔记。 以下笔记应用 Python 版本是 3.8。 以下是本篇笔记目录: re.findall表达式语法 匹配字符串类型 \b-匹配空字符串,但只在单词开始或结尾\B-匹配空字符串,不能在结尾或结尾\d-匹配十进制数字\D-匹配非十进制字符\s-匹配空白字符\S-匹配非空白字符\w-匹配字符\W-匹配非单词字符匹配字符串呈现地位 1) \A-只匹配字符串开始 2) \Z-只匹配字符串结尾 3) ^-匹配字符串结尾 4) $-匹配字符串结尾匹配字符串数量 1) *-匹配反复 0 到 n 次 2) +-匹配反复 1 到 n 次 3) ?-匹配反复 0 到 1 次 4) {}-指定匹配反复次数 a. {m}-只匹配反复 m 次 b. {m,n}-匹配反复 m 到 n 次匹配字符串汇合 1) 字符能够独自列出 2) 能够示意字符范畴 3) 特殊字符在汇合里只会匹配其原始字符含意 4) 字符类 \s 或 \w 能够在汇合里应用 5) 取反操作能够应用 ^其余匹配类型 ...

February 25, 2024 · 5 min · jiezi

关于后端:深入浅出JVM八之类加载器

前文曾经形容Java源文件通过前端编译器后变成字节码文件,字节码文件通过类加载器的类加载机制在Java虚拟机中生成Class对象 前文深入浅出JVM(六)之前端编译过程与语法糖原理重点形容过编译的过程 前文深入浅出JVM(三)之HotSpot虚拟机类加载机制重点形容过类加载机制的过程 本篇文章将重点聊聊类加载器,围绕类加载器深入浅出的解析类加载器的分类、品种、双亲委派模型以及从源码方面推导出咱们的论断 类加载器简介什么是类加载器?类加载器通过类的全限定类名进行类加载机制从而生成Class对象 Class对象中蕴含该类相干类信息,通过Class对象可能应用反射在运行时阶段动静做一些事件 显示加载与隐式加载类加载器有两种形式进行加载,一种是在代码层面显示的调用,另一种是当程序遇到创建对象等命令时自行判断该类是否进行过加载,未加载就先进行类加载 显示加载:显示调用ClassLoader加载class对象 隐式加载:不显示调用ClassLoader加载class对象(因为虚构机会在第一次应用到某个类时主动加载这个类)  //显示类加载 第7章虚拟机类加载机制.User为全限定类名(包名+类名) Class.forName("第7章虚拟机类加载机制.User");              //隐式类加载 new User();    唯一性与命名空间判断两个类是否完全相同可能并不是咱们自认为了解的那样,类在JVM中的唯一性须要依据类自身和加载它的类加载器 唯一性 所有类都由它自身和加载它的那个类在JVM中确定唯一性也就是说判断俩个类是否为同一个类时,如果它们的类加载器都不同那必定不是同一个类命名空间 每个类加载有本人的命名空间,命名空间由所有父类加载器和该加载器所加载的类组成同一命名空间中,不存在类残缺名雷同的俩个类不同命名空间中,容许存在类残缺名雷同的俩个类(多个自定义类加载加载同一个类时,会在各个类加载器中生成对应的命名,且它们都不是同一个类)基本特征类加载器中有一些根本个性,比方子类加载器能够拜访父类加载器所加载的类、父类加载过的类子类不再加载、双亲委派模型等 可见性 子类加载器能够拜访父类加载器所加载的类*(命名空间蕴含父类加载器加载的类)单一性 因为可见性,所以父类加载器加载过的类,子类加载器不会再加载同一级的自定义类加载器可能都会加载同一个类,因为它们互不可见双亲委派模型 由哪个类加载器来进行类加载的一套策略,后续会具体阐明类加载器分类类加载器能够分成两种,一种是疏导类由非Java语言实现的,另一种是由Java语言实现的自定义类加载器 疏导类加载器 (c/c++写的Bootstrap ClassLoader)自定义类加载器:由ClassLoader类派生的类加载器类(包含扩大类,零碎类,程序员自定义加载器等)零碎(应用程序)类加载器和扩大类加载器是Launcher的外部类,它们间接实现了ClassLoader 留神平时说的零碎(应用程序)类加载器的父类加载器是扩大类加载器,而扩大类加载器的父类加载器是启动类加载器,都是"逻辑"上的父类加载器 实际上扩大类加载器和零碎(应用程序)类加载器间接继承的ClassLoader中有一个字段parent用来示意本人的逻辑父类加载器 类加载器品种启动(疏导)类加载器 Bootstrap Classloader c++编写,无奈间接获取加载外围库<JAVA_HOME>\lib\局部jar包不继承java.lang.ClassLoader,没有父类加载器加载扩大类加载器和应用程序类加载器,并指定为它们的父类加载器扩大类加载器 Extension Classloader加载扩大库<JAVA_HOME>\lib\ext*.jar间接继承java.lang.ClassLoader,父类加载器为启动类加载器应用程序(零碎)类加载器 App(System) Classloader 最罕用的加载器负责加载环境变量classpath或java.class.path指定门路下的类库 ,个别加载咱们程序中自定义的类间接继承java.lang.ClassLoader,父类加载器为扩大类加载器应用ClassLoader.getSystemClassLoader()取得自定义类加载器(实现ClassLoader类,重写findClass办法)通过代码来演示:  public class TestClassLoader {     public static void main(String[] args) {         URL[] urLs = Launcher.getBootstrapClassPath().getURLs();         /*         启动类加载器能加载的api门路:         file:/D:/Environment/jdk1.8.0_191/jre/lib/resources.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/rt.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/sunrsasign.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/jsse.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/jce.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/charsets.jar         file:/D:/Environment/jdk1.8.0_191/jre/lib/jfr.jar         file:/D:/Environment/jdk1.8.0_191/jre/classes         */         System.out.println("启动类加载器能加载的api门路:");         for (URL urL : urLs) {             System.out.println(urL);        }           /*         扩大类加载器能加载的api门路:         D:\Environment\jdk1.8.0_191\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext         */         System.out.println("扩大类加载器能加载的api门路:");         String property = System.getProperty("java.ext.dirs");         System.out.println(property);                  //加载咱们自定义类的类加载器是AppClassLoader,它是Launcher的外部类         ClassLoader appClassLoader = TestClassLoader.class.getClassLoader();         //sun.misc.Launcher$AppClassLoader@18b4aac2          System.out.println(appClassLoader);                  //AppClassLoader的上一层加载器是ExtClassLoader,它也是Launcher的外部类         ClassLoader extClassloader = appClassLoader.getParent();         //sun.misc.Launcher$ExtClassLoader@511d50c0         System.out.println(extClassloader);                  //实际上是启动类加载器,因为它是c/c++写的,所以显示null         ClassLoader bootClassloader = extClassloader.getParent();         //null          System.out.println(bootClassloader);                  //1号测试:根本类型数组 的类加载器         int[] ints = new int[10];         //null          System.out.println(ints.getClass().getClassLoader());                  //2号测试:零碎提供的援用类型数组 的类加载器         String[] strings = new String[10];         //null          System.out.println(strings.getClass().getClassLoader());                  //3号测试:自定义援用类型数组 的类加载器         TestClassLoader[] testClassLoaderArray = new TestClassLoader[10];         //sun.misc.Launcher$AppClassLoader@18b4aac2                System.out.println(testClassLoaderArray.getClass().getClassLoader());          //4号测试:线程上下文的类加载器         //sun.misc.Launcher$AppClassLoader@18b4aac2         System.out.println(Thread.currentThread().getContextClassLoader());    } }从下面能够得出结论 ...

February 24, 2024 · 5 min · jiezi

关于后端:CS-83183-3D-Reconstruction

CS 83/183, Winter 2024 Programming Assignment 3 3D Reconstruction Due Date: (Sunday) February 18, 2023 23:59 (ET) Instructions Integrity and collaboration: Students are encouraged to work in groups but each student must write their own code and write-up. If you work as a group, include the names of your collaborators in your write up. Code should NOT be shared or copied. Please DO NOT use external code or large-language models such as chatgpt unless permitted. Plagiarism is strongly prohibited and may lead to failure of this course.Start early! Especially if you are not familiar with Python.Questions: If you have any question, please look at piazza first. Other students may have encountered the same problem, and is solved already. If not, post your question on the discussion board. TAs will respond as soon as possible.Write-up: Items to be included in the writeup are mentioned in each question, and summarized in the Writeup section. Please note that we DO NOT accept handwritten scans for your write-up in this assignment. Please type your answers to theory questions and discussions for experiments electronically.Handout: The handout zip file contains 3 items. assgn3.pdf is the assignment handout. data contains 2 temple image files from the Middlebury MVS Temple Data set, and some npz files. python contains the scripts that you will make use of in this homework.Submission: Your submission for this assignment should be a zip file, <dartmouthID>.zip, composed of your write-up, your Python implementations (including helper functions), and your implementations, results for extra credit (optional). Your final upload should have the files arranged in this layout:• <dartmouthID>.zip ...

February 24, 2024 · 19 min · jiezi

关于后端:RocksDB深度解析

RocksDB是被宽泛采纳的内存嵌入式键值存储引擎,本文介绍了RocksDB的架构、技术原理、性能优化,帮忙读者深刻理解RocksDB,从而更好的应用这项技术。原文: RocksDB — A Deep Dive into the Internals of an Embedded Key-Value Storage Engine 指标读者: 有趣味深刻理解亚马逊 DynamoDB、Cassandra等NoSQL数据库以及LevelDB和RocksDB等嵌入式键值存储的外部原理,并相熟数据库管理系统(DBMS)的根本组件(尤其是存储引擎)的读者。 导言RocksDB是当先的嵌入式键值存储引擎,已在各行各业失去广泛应用。Meta、微软、Netflix和Uber等出名公司都已将RocksDB集成到生产环境。这些公司高度依赖RocksDB来治理和存储大规模数据,为音讯传送、用户流动跟踪和外部零碎等要害利用提供能源。 Meta宽泛应用RocksDB来解决海量数据的治理和存储,反对消息传递、用户流动跟踪和外部零碎等基本功能。此外,LinkedIn利用RocksDB高效解决其音讯平台中的高写入和高读取工作负载。通过RocksDB,LinkedIn可确保为用户提供晦涩牢靠的性能。 Airbnb依赖RocksDB来治理用户数据和会话存储,优化整体性能,晋升用户体验。通过应用RocksDB,Airbnb进步了数据管理和会话解决能力,从而在其平台上实现了更加完满的用户体验。 Netflix依附RocksDB进行会话治理和元数据存储,并获益于其性能和可靠性。这使Netflix可能向数百万用户提供不间断的流媒体服务,确保晦涩牢靠的娱乐体验。 Uber依附RocksDB保障疾速牢靠的拜访要害数据,实现实时决策,促成顺利经营。通过利用RocksDB的性能,Uber加强了高效解决和检索重要信息的能力。 这些知名企业对RocksDB的采纳进一步坚固了RocksDB作为弱小、多功能存储引擎的名誉。RocksDB久经考验的性能和可靠性使其成为解决大规模数据和高要求工作负载的首选。 RocksDB是什么RocksDB是一种嵌入式数据库,2012年基于谷歌的LevelDB分叉而来,最后由Dhruba Borthakur在Facebook创立,目标是进步服务器工作负载性能。目前,RocksDB由Meta开发和保护。 RocksDB以C++语言编写,反对通过绑定嵌入到以C、C++、Rust、Go和Java等多种语言编写的应用程序中。这种灵活性使得开发人员能够将RocksDB集成到本人的应用程序,而无需思考应用的编程语言。 数据模型基于键值对存储数据,任意字节数组可作为键,并可存储相干值。字节数组能够是字符串、整数、序列化对象或自定义数据结构。任何类型的数据都能够作为值存储。键和值都是任意长度的字节数组,没有任何预约义数据类型。次要操作Put(Key, Value) - 插入新的键值对或更新现有键值。Merge(Key, Value) - 将新值与给定键的现有值合并。Delete(Key) - 从RocksDB中删除与指定键值相干的键值对。检索值Get(Key) - 获取与特定键相干的值。范畴扫描和迭代器Seek(key_prefix) - 匹配指定键的前缀或大于键的前缀。Value() - 检索与以后键相干的值。Next() - 将迭代器挪动到指定范畴内的下一个键值对。高级操作filter.set_expiration_time(1),而后 compact(filter) - 当运行压缩过滤器时,任何超过 1 秒的数据都将从数据库中删除。snapshot.take(database) - 创立特定工夫点的数据库正本,可用于备份数据或测试对数据库的更改,而不会影响实时数据。开发人员能够利用RocksDB的键值数据模型来构建更简单的零碎,如反转索引、文档数据库、SQL数据库、缓存零碎和音讯代理,这些零碎须要在RocksDB的根底上实现更多层次的逻辑和性能。 反向索引 - 依据术语或关键词检索文档。文档数据库 - 将文档存储为值,并应用惟一标识符或其余特定于文档的键来无效检索和解决数据。SQL 数据库 - 实现SQL查问解析、执行和索引。缓存零碎 - 通过在内存中存储常常拜访的数据,进步应用程序性能。音讯代理 - 促成分布式系统之间的通信和数据交换。例如,要用RocksDB建设反向索引零碎,开发人员须要: 设计存储反向索引的数据模式执行标记化和索引逻辑开发查询处理机制例如,要创立文档数据库,开发人员须要: 定义文档数据模式解决索引和查问操作管理文件级操作嵌入式数据库是集成到应用程序中的数据库,没有独立程序,有一些次要特点。 与应用程序集成 - 防止跨过程通信开销共享资源 - 防止跨过程通信开销无内置服务 - 无奈通过网络近程拜访不足分布式性能 - 没有容错、冗余或分片机制轻便高效RocksDB架构准则RocksDB是Meta开发的一种宽泛应用的嵌入式数据库库,实现了日志构造合并树(LSM-tree,log-structured merge-tree)数据结构。RocksDB架构的原理能够通过以下方面来了解: ...

February 24, 2024 · 2 min · jiezi

关于后端:Apache-Calcite-动态数据管理框架整合-csv-实战笔记

序言咱们在 Apache Calcite 动态数据治理框架介绍 介绍了 calcite 的基本功能,本文一起来看一下如何实现一个 csv 的 sql 查问。 入门例子依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>calcite-learn</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>calcite-learn-basic</module> </modules> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <calcite.version>1.20.0</calcite.version> </properties> <dependencies> <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-core</artifactId> <version>${calcite.version}</version> </dependency> <dependency> <groupId>org.apache.calcite</groupId> <artifactId>calcite-example-csv</artifactId> <version>${calcite.version}</version> </dependency> <!-- Add other dependencies, e.g., database driver --> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build></project>测试 csv创立文件夹: D:\github\calcite-learn\calcite-learn-basic\src\main\resources\csv上面防对应的测试 csv 文件: depts.csvEMPNO:long,NAME:string,DEPTNO:int,GENDER:string,CITY:string,EMPID:int,AGE:int,SLACKER:boolean,MANAGER:boolean,JOINEDAT:date100,"Fred",10,,,30,25,true,false,"1996-08-03"110,"Eric",20,"M","San Francisco",3,80,,false,"2001-01-01"110,"John",40,"M","Vancouver",2,,false,true,"2002-05-03"120,"Wilma",20,"F",,1,5,,true,"2005-09-07"130,"Alice",40,"F","Vancouver",2,,false,true,"2007-01-01"测试类package com.github.houbb.calcite.learn.basic;import org.apache.calcite.adapter.csv.CsvSchema;import org.apache.calcite.adapter.csv.CsvTable;import org.apache.calcite.jdbc.CalciteConnection;import org.apache.calcite.schema.SchemaPlus;import java.io.File;import java.sql.*;import java.util.Properties;public class CsvDemo { public static void main(String[] args) throws Exception { // 0.获取csv文件的门路,留神获取到文件所在下层门路就能够了 String path = "D:\\github\\calcite-learn\\calcite-learn-basic\\src\\main\\resources\\csv\\"; // 1.构建CsvSchema对象,在Calcite中,不同数据源对应不同Schema,比方CsvSchema、DruidSchema、ElasticsearchSchema等 CsvSchema csvSchema = new CsvSchema(new File(path), CsvTable.Flavor.SCANNABLE); // 2.构建Connection // 2.1 设置连贯参数 Properties info = new Properties(); // 不辨别sql大小写 info.setProperty("caseSensitive", "false"); // 2.2 获取规范的JDBC Connection Connection connection = DriverManager.getConnection("jdbc:calcite:", info); // 2.3 获取Calcite封装的Connection CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); // 3.构建RootSchema,在Calcite中,RootSchema是所有数据源schema的parent,多个不同数据源schema能够挂在同一个RootSchema下 // 以实现查问不同数据源的目标 SchemaPlus rootSchema = calciteConnection.getRootSchema(); // 4.将不同数据源schema挂载到RootSchema,这里增加CsvSchema rootSchema.add("csv", csvSchema); // 5.执行SQL查问,通过SQL形式拜访csv文件 String sql = "select * from csv.depts"; Statement statement = calciteConnection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); // 6.遍历打印查问后果集 printResultSet(resultSet); } public static void printResultSet(ResultSet resultSet) throws SQLException { // 获取 ResultSet 元数据 ResultSetMetaData metaData = resultSet.getMetaData(); // 获取列数 int columnCount = metaData.getColumnCount(); System.out.println("Number of columns: " + columnCount); // 遍历 ResultSet 并打印后果 while (resultSet.next()) { // 遍历每一列并打印 for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnName(i); String columnValue = resultSet.getString(i); System.out.println(columnName + ": " + columnValue); } System.out.println(); // 换行 } }}测试成果Number of columns: 10EMPNO: 100NAME: FredDEPTNO: 10GENDER: CITY: EMPID: 30AGE: 25SLACKER: trueMANAGER: falseJOINEDAT: 1996-08-03EMPNO: 110NAME: EricDEPTNO: 20GENDER: MCITY: San FranciscoEMPID: 3AGE: 80SLACKER: nullMANAGER: falseJOINEDAT: 2001-01-01EMPNO: 110NAME: JohnDEPTNO: 40GENDER: MCITY: VancouverEMPID: 2AGE: nullSLACKER: falseMANAGER: trueJOINEDAT: 2002-05-03EMPNO: 120NAME: WilmaDEPTNO: 20GENDER: FCITY: EMPID: 1AGE: 5SLACKER: nullMANAGER: trueJOINEDAT: 2005-09-07EMPNO: 130NAME: AliceDEPTNO: 40GENDER: FCITY: VancouverEMPID: 2AGE: nullSLACKER: falseMANAGER: trueJOINEDAT: 2007-01-01参考资料Apache Calcite 疾速入门指南 ...

February 24, 2024 · 2 min · jiezi

关于后端:Apache-Calcite-动态数据管理框架入门介绍

原文地址: Apache Calcite 动态数据治理框架介绍 背景随着数据规模的一直增长和数据源的多样化,开发人员须要面对各种挑战,如何高效地治理、查问和剖析海量数据成为了一个迫切的问题。 在这样的背景下,呈现了许多优良的开源组件,它们提供了丰盛的性能和灵便的解决方案,帮忙开发者轻松地解决各种数据处理工作。 Apache calcite 是什么?Apache Calcite 是一个动态数据治理框架,旨在提供 SQL 解析、查问优化和执行的性能。 它容许开发者构建自定义的 SQL 解决管道,能够在各种数据源之间进行查问和转换,例如关系型数据库、NoSQL 数据库、流数据、文件等。 上面是对于 Apache Calcite 的具体介绍: 次要个性SQL 解析和剖析: Apache Calcite 提供了弱小的 SQL 解析器和语法分析器,能够将 SQL 查问转换成外部的查问示意模式。它反对 ANSI SQL 规范,并且提供了扩展性,能够扩大以反对特定于数据源的语法和语义。查问优化: Calcite 提供了多种查问优化技术,包含但不限于谓词下推、投影打消、常量折叠等,以优化查问打算的执行效率。通过代价估算和规定匹配,它可能抉择最优的查问执行打算。可扩展性: Apache Calcite 是一个高度可扩大的框架,容许开发者编写自定义的优化规定和转换器,以适应不同的数据源和查问需要。通过扩大 Calcite 的接口,能够反对新的数据源、新的优化规定等。数据源适配器: 它提供了一组数据源适配器,能够连贯到各种数据源,包含关系型数据库(如MySQL、PostgreSQL等)、NoSQL 数据库(如Apache Cassandra、MongoDB等)、文件系统、Kafka 等。这些适配器使得能够通过 SQL 查问来拜访和操作不同类型的数据。流数据处理: Calcite 还反对流数据处理,能够解决实时数据流,并且反对间断查问。集成: 它能够与 Apache Hive、Apache Spark 等生态系统中的其余组件无缝集成,使得用户能够在现有的基础架构上轻松地利用 Calcite 的性能。Apache calcite 工作原理SQL 解析和剖析: 用户提交 SQL 查问,Calcite 解析器将其解析成形象语法树(AST),而后进行语法分析,构建查问的逻辑示意。查问优化: 在生成查问的逻辑示意之后,Calcite 会利用一系列的优化规定和转换器来生成最优的执行打算。这些优化规定包含代价估算、谓词下推、投影打消、关联打消等,以及用户定义的自定义规定。执行打算生成: 优化器生成的最优执行打算被转换成可执行的物理操作符序列。这些物理操作符能够间接执行查问,或者通过连贯到特定数据源的适配器来执行。执行查问: 最终生成的执行打算被传递给执行引擎,执行引擎负责将其转换为理论的数据操作,并从数据源中检索和解决数据。应用场景:数据查问:通过 SQL 查问来拜访和操作各种数据源中的数据,包含关系型数据库、NoSQL 数据库、文件系统等。查问优化:对简单的查问进行优化,以进步查问性能和效率。数据集成:将不同数据源中的数据整合到一起,并且通过对立的 SQL 接口来进行查问和解决。实时数据处理:解决实时流数据,并且反对间断查问。构建自定义 SQL 解决管道:通过扩大 Calcite 的性能来构建自定义的 SQL 解决管道,以满足特定的业务需要。Apache Calcite 是一个功能强大且灵便的数据管理框架,能够帮忙开发者轻松地实现各种简单的数据查问和解决工作,并且能够与现有的数据处理生态系统无缝集成。 ...

February 24, 2024 · 2 min · jiezi

关于后端:深入浅出JVM七之执行引擎的解释执行与编译执行

本篇文章围绕执行引擎,深入浅出的解析执行引擎中解释器与编译器的解释执行和编译执行、执行引擎的执行形式、逃逸剖析带来的栈上调配、锁打消、标量替换等优化以及即时编译器编译对热点代码的探测 执行引擎hotspot执行引擎结构图执行引擎分为解释器、JIT即时编译器以及垃圾收集器 执行引擎通过解释器/即时编译器将字节码指令解释/编译为对应OS上的的机器指令 本篇文章次要围绕解释器与即时编译器,垃圾收集器将在后续文章解析 解释执行与编译执行Java虚拟机执行引擎在执行Java代码时,会有两种抉择:解释执行和编译执行 解释执行:通过字节码解释器把字节码解析为机器语言执行 编译执行:通过即时编译器产生本地代码执行 Class文件中的代码到底是解释执行还是编译执行只有Java虚拟机本人能力判断精确 编译过程 编译流程在前一篇文章深入浅出JVM之前端编译过程与语法糖原理曾经阐明,在本篇文章中不再概述 经典编译原理: 1.对源码进行词法,语法分析解决 2.把源码转换为形象语法树 javac编译器实现了对源码进行词法,语法分析解决为形象语法树,再遍历形象语法树生成线性字节码指令流的过程 剩下的指令流有两种形式执行 由虚拟机外部的字节码解释器去将字节码指令进行逐行解释 (解释执行)或优化器(即时编译器)优化代码最初生成指标代码 (编译执行)执行引擎流程图 解释器与编译器解释器作用: 对字节码指令逐行解释 长处: 程序启动,解释器立刻解释执行 毛病: 低效 即时编译器 (just in time compiler)Java中的"编译期"不确定 可能说的是执行javac指令时的前端编译器 (.java->.class)也可能是后端编译器JIT (字节指令->机器指令)还可能是AOT编译器(动态提前编译器) (.java->机器指令)作用: 将办法编译成机器码缓存到办法区,每次调用该办法执行编译后的机器码 长处: 即时编译器把代码编译成本地机器码,执行效率高,高效 毛病: 程序启动时,须要先编译再执行 执行引擎执行形式执行引擎执行形式大抵分为3种 -Xint: 齐全采纳解释器执行 -Xcomp: 优先采纳即时编译器执行,解释器是后备抉择 -Xmixed: 采纳解释器 + 即时编译器 hotspot中有两种JIT即时编译器 Client模式下的C1编译器:简略优化,耗时短(C1优化策略:办法内联,去虚拟化,冗余打消) Server模式下的C2编译器:深度优化,耗时长 (C2次要是逃逸剖析的优化:标量替换,锁打消,栈上调配) 分层编译策略:程序解释执行(不开启逃逸剖析)能够触发C1编译,开启逃逸剖析能够触发C2编译 解释器,C1,C2编译器同时工作,热点代码可能被编译屡次 解释器在程序刚刚开始的时候解释执行,不须要承当监控的开销 C1有着更快的编译速度,能为C2编译优化争取更多工夫 C2用高复杂度算法,编译优化水平很高的代码 逃逸剖析带来的优化当对象作用域只在某个办法时,不会被外界调用到,那么这个对象就不会产生逃逸 开启逃逸剖析后,会剖析对象是否产生逃逸,当不能产生逃逸时会进行栈上调配、锁打消、标量替换等优化 栈上分配内存 //-Xms1G -Xmx1G -XX:+PrintGCDetails  public class StackMemory {     public static void main(String[] args) {         long start = System.currentTimeMillis();          for (int i = 0; i < 10000000; i++) {             memory();        }          System.out.println("破费工夫:"+(System.currentTimeMillis()-start)+"ms");          try {             TimeUnit.SECONDS.sleep(1000);        } catch (InterruptedException e) {             e.printStackTrace();        }    }      private static void memory(){         StackMemory memory = new StackMemory();    } }-XX:-DoEscapeAnalysis 破费工夫:63ms (未开启逃逸剖析) ...

February 24, 2024 · 2 min · jiezi

关于后端:Git-版本控制系统的完整指南

什么是 Git?Git 是一个风行的版本控制系统。它是由 Linus Torvalds 于 2005 年创立的,自那时以来由 Junio Hamano 保护。 它用于: 跟踪代码更改跟踪谁做出了更改编写合作Git 做什么?应用仓库治理我的项目克隆我的项目以在本地正本上工作应用暂存和提交来管制和跟踪更改分支和合并容许在我的项目的不同局部和版本上进行工作将我的项目的最新版本拉到本地正本将本地更新推送到主我的项目应用 Git在文件夹上初始化 Git,使其成为一个仓库Git 当初会创立一个暗藏的文件夹,以跟踪该文件夹中的更改当文件被更改、增加或删除时,它被视为已批改你抉择要暂存的已批改文件已暂存的文件被提交,这会促使 Git 存储文件的永恒快照Git 容许你查看每个提交的残缺历史。你能够复原到以前的任何提交。Git 不会在每个提交中存储文件的独自正本,而是跟踪每个提交中所做的更改!切换平台:将焦点转向 GitHub将焦点转向 Bitbucket将焦点转向 GitLab为什么应用 Git?超过 70% 的开发者应用 Git!开发者能够从世界任何中央协同工作。开发者能够查看我的项目的残缺历史。开发者能够还原到我的项目的晚期版本。什么是 GitHub?Git 不同于 GitHub。GitHub 制作应用 Git 的工具。GitHub 是世界上最大的源代码托管服务,并自 2018 年起由 Microsoft 领有。在本教程中,咱们将专一于应用 Git 与 GitHub。 Git 暂存环境Git 的外围性能之一是暂存环境和提交的概念。 当你工作时,你可能会增加、编辑和删除文件。但无论何时你达到一个重要阶段或实现工作的一部分,都应该将文件增加到暂存环境。 已暂存的文件是筹备提交到你正在工作的仓库的文件。不久后,你将更多地理解提交。 目前,咱们已实现了对 index.html 的工作。所以咱们能够将它增加到暂存环境中: git add index.html 文件应该已被暂存。让咱们查看状态: git status 在主分支上 尚未提交 待提交的更改: (应用 "git rm --cached ..." 来勾销暂存) 新文件: index.html 当初该文件已被增加到暂存环境。 Git 增加多个文件你还能够一次暂存多个文件。让咱们向咱们的工作文件夹增加 2 个文件。再次应用文本编辑器。 ...

February 23, 2024 · 2 min · jiezi

关于后端:sambamba-samtools-的高效平替工具

sambamba — samtools 的高效平替工具sambamba 是一个 BAM 文件解决工具。 它应用了 D 语言的多线程和异步 IO 个性,实现了高效的并行化解决。sambamba 能够在多核 CPU 上同时运行多个工作,利用硬盘和内存的带宽,进步了处理速度。sambamba 还应用了一些优化算法和数据结构,比方疾速排序,哈希表,位图等,缩小了内存占用和磁盘读写。 sambamba 反对 samtools 和 picard 的大部分性能,而且速度更快,内存占用更少,操作更简略。<u>sambamba 不仅能够对 BAM 文件进行排序、索引、过滤、统计、标记反复等常见的操作,还能够进行一些非凡的性能,比方区域过滤,标记反复序列,检测构造变异等。</u>sambamba 还反对多种输出和输入格局,比方 CRAM、SAM、BED、VCF 等,让咱们能够灵便地解决各种数据类型。 此外,sambamba 还补救了 samtools 无奈对超过 512Mb 长度的染色体建设 bam 文件索引的缺点,例如: $ samtools index -b test.sort.bam test.sort.bam.bai[E::hts_idx_check_range] Region 536870922..536871063 cannot be stored in a bai index. Try using a csi index[E::sam_index] Read 'E00548:269:HV7NVCCXY:3:2117:26494:57301' with ref_name='chr1H', ref_length=558535432, flags=81, pos=536870923 cannot be indexedsamtools index: failed to create index for "Atlas.sort.bam": Numerical result out of range错误信息表明区域 536870922..536871063 无奈存储在 .bai 索引中,并倡议尝试应用 .csi 索引。然而 GATK 等一些生信工具不反对 .csi 格局的索引文件。sambamba 可能给最大参考序列长度的 bam 文件构建 bai 索引。 ...

February 23, 2024 · 3 min · jiezi

关于后端:IDEA-Debug框的-show-execution-point按钮没了

在这里右键: Add Action: 搜寻增加: 本文由博客一文多发平台 OpenWrite 公布!

February 23, 2024 · 1 min · jiezi

关于后端:Kitex-支持-Dubbo-协议助力多语言云原生生态融合

作者:王宇轩(github: DMwangnima),Kitex Committer一、背景Kitex 是字节跳动基础架构服务框架团队推出的 Go 微服务 RPC 框架,反对 Thrift、Kitex Protobuf、gRPC 等音讯协定,具备高性能、强可扩大的特点。于 2021 年 9 月正式开源后,已在多家内部企业胜利落地,为他们带来了实在的老本、性能和稳定性收益。 很多企业用户在应用 Kitex 革新服务的过程中,须要 Kitex 能与现有的 Dubbo 框架实现的服务进行通信,这与 CloudWeGo 社区踊跃拓展生态的指标不约而同,因而 Dubbo 互通我的项目 codec-dubbo 应运而生。 在社区同学的热情帮助下,目前 codec-dubbo 能做到 Kitex 与 Dubbo-Java,Kitex 与 Dubbo-Go 互通,反对 Dubbo 用户向 Kitex 迁徙。 本文将以方正证券利用 Kitex 与 codec-dubbo 胜利进行服务革新为例,对革新过程中应用到的 codec-dubbo 次要性能进行论述,并简要剖析其中的实现细节。 二、企业落地案例方正证券原有的服务采纳 Java 和 Dubbo 框架编写,两者稳固且通过了大量场景的验证,合乎他们的生产和开发需要。以申请量较大的小方个股详情页为例,高峰期的接口 QPS 在 3-4k,应用 16 台 16 Core 64G 虚拟机进行承载。 随着云原生架构的衰亡,凭借内存占用与执行效率的劣势以及人造适配云原生,Go 逐步成为构建企业服务的重要技术选项。为了更好地降本增效,综合思考老本、性能和稳定性等因素后,他们决定在新建利用上由 Java 转向 Go,引入 Kitex,Hertz 等 CloudWeGo 我的项目进行服务开发与重构,并整体迁徙至 Kubernetes 环境。 ...

February 23, 2024 · 4 min · jiezi

关于后端:这才开工没几天收到Offer了简历改的好找工作没烦恼

喜报喜报这才动工没几天,就收到了喜报! 就像下面截图中所说的一样:简历改了真的有用。 我也和大家分享一下优化简历的技巧,心愿对大家有帮忙,把握住金三银四的机会,都能顺利上岸,升职加薪! 思路很重要咱们以Go后端开发工程师的简历举例子,其余岗位也能够参考我的思路。 思路是最重要的:其余岗位的技术栈,知识点依据你的状况替换掉就好了。 我按程序介绍一下,简历中最重要的几个模块怎么写: 专业技能(集体劣势):纯熟应用Go进行我的项目开发,对Slice、Map、Goroutine、Channel有深刻理解,善于并发编程;纯熟应用Gin、GoFrame、Go-zero、Go-micro、kratos等web和微服务框架,相熟熔断,限流,服务治理等;深刻了解CSP模型,深刻了解GC垃圾回收机制和三色标记法,有过理论调优教训;相熟MySQL的存储引擎、事务隔离级别、锁、索引,有MySQL的性能调优教训;相熟 Redis 长久化机制、过期策略以及集群部署;相熟RabbitMQ音讯队列事务音讯底层原理,把握音讯失落、音讯反复等问题的解决方案;纯熟应用Docker和K8S,有CICD教训;善于麻利开发;纯熟应用常见的设计模式;精通基于 LNMP 环境的编程,具备扎实的PHP基础知识,了解面向对象编程思维。纯熟应用 Yii、ThinkPHP和Laravel等框架进行疾速开发,理解根本的外围源代码,相熟swoole 扩大。(留神:8和9的思路是这样的,如果有其余语言的开发教训,像下面的PHP教训一样写在最初) 留神:下面提到的Gin GoFrame GoZero的框架,联合本人状况批改或者删减,保留本人善于的框架下面提到的NSQ、Kafka、RabbitMQ,联合本人的状况批改或者删减,保留本人善于的技术栈工作经验:最终目标是让面试官感觉你之前任职的公司挺牛逼,你负责的工作也挺牛逼能够这么写:2行之内写分明之前所在的公司所属行业(教育、电商),是什么类型的公司(大厂、集团公司、国企),本人在公司负责什么(技术研发、团队治理、和客户对接等等),达到了什么成果,你或者公司获得了什么业绩。比方:2018年退出xxxx(中国xxx视频第一门户),做技术负责人,负责公司自有全平台的架构设计和开发,包含:网站+APP+小程序+CMS+公众号+经营零碎。是一位懂产品设计的技术负责人。我的项目介绍:肯定尽可能多的写分明技术栈,比方:go+gozero+etcd+mysql+redis+kafka+elasticsearch+docker+k8s用最通俗易懂的话介绍分明我的项目,不要超过2行。你就想给本人父母怎么介绍你做的我的项目,他们能听懂,面试官(HR)就必定能听懂了。工作内容: 用xxx技术,解决了xxx问题工作业绩: 站在公司的角度:你做的哪些事件,为公司降本增效了站在团队的角度:你做的哪些事件,进步团队的效率了站在我的项目的角度:你做的哪些事件,进步我的项目的稳定性了,进步接口响应速度了站在技术的角度:你攻克了哪些技术难题,做了哪些有亮点、有难点的事件思维导图梳理法:如果切实想不分明本人我的项目的难点和亮点,倡议用上面思维导图的形式,尽可能多的补充状况性能点、以及每个性能点下对应的业务场景和技术计划。基于思维先做加法,再做减法。先尽可能多的列出,整顿,而后再合并总结。这样就不发愁简历中没有可写的了。 当然,你也能够私信我,我给你支支招。 自我评估(加分项):本人的博客地址本人加入过的开源我的项目以上这两个是最强有力的加分项,如果没有也要通过例子来证实本人“酷爱技术”,而不是水灵灵一句“酷爱技术”。好了,以上就是我给大家优化简历的倡议。 咱们 待业训练营 和 升职加薪星球 的敌人们依照我的思路优化简历之后,都起到了很好的成果。 以上内容如果对你有帮忙,欢送点赞、留言、关注。 更欢送你转载分享进来:送人玫瑰,手留余香嘛。 又出问题啦也欢送你理解一下咱们的待业训练营,辅导到你找到工作为止的那种: 咱们又出问题啦!大厂Offer集锦!遥遥领先! 这些敌人赢麻了! 这是一个专一程序员升职加薪の常识星球 答疑解惑须要「简历优化」、「就业辅导」、「职业规划」的敌人能够分割我。 一对一辅导的那种呦! 面试真题共享群对了,咱们筹备搞一个金三银四面试真题共享群,互通有无,一起刷题提高,没准能让你能刷到本人动向公司的最新面试题呢。 感兴趣的敌人们能够在社区私信我。 或者加我微信:wangzhongyang1993 关注我的同名公众号:王中阳Go

February 23, 2024 · 1 min · jiezi

关于后端:全面解析-Redis-持久化RDBAOF与混合持久化

Redis 长久化前言: 在数字时代,数据的价值越来越被人们所器重。但数据只有在通过妥善保存和治理时,能力真正施展其潜在价值。对于应用 Redis 这一热门的内存数据库的开发者和企业来说,数据的长久化无疑是一个必须面对的重要议题。 咱们都晓得,Redis 以其卓越的性能和灵便的数据结构而著称,但如何确保内存中的数据不因突发事件而失落?如何在确保性能的前提下,为数据提供一个更加巩固的避风港? 本文将为你揭开 Redis 长久化的神秘面纱,探讨其背地的机制,并帮忙你为你的利用抉择适合的长久化策略。 Redis与内存数据库的个性为什么Redis是内存数据库?Redis是一种键值存储系统,其数据次要存储在内存中,因而被称为内存数据库。与传统的磁盘存储数据库不同,Redis的设计初衷是为了提供高速、低提早的数据拜访。因为数据间接存储在内存中,能够防止磁盘I/O的开销,从而实现极高的读写速度。 例子: 设想一下你在家里找一本书。如果这本书就放在你的桌子上(相当于内存),你能够立即拿到它。但如果它放在地下室的一个盒子里(相当于磁盘),那你可能须要破费更多工夫去找。Redis的工作形式就像那本放在桌子上的书。 内存数据库的长处和毛病长处: 速度:内存数据库如Redis可能提供疾速的读写能力,因为内存的访问速度远超过磁盘。低提早:数据存取的响应工夫短,适宜须要疾速响应的利用。灵活性:因为数据结构存储在内存中,Redis等内存数据库反对丰盛的数据类型和操作。简化的数据模型:键值存储形式简化了数据模型,便于开发和保护。毛病: 老本:内存通常比磁盘更低廉,大量的数据存储须要大量的内存,可能导致高老本。数据持久性危险:如果没有适合的长久化策略,忽然的零碎解体可能导致数据失落。数据容量限度:因为依赖内存,数据的容量受到物理内存大小的限度。什么是长久化长久化的定义: 长久化,顾名思义,指的是将短暂的、易失的数据转化为长时间保留,且不易失落的格局。在数据库的语境中,长久化经常指的是将内存中的数据保留到硬盘或其余长期存储介质中,从而确保即便在零碎解体、断电或其余突发事件中,数据也不会失落。 长久化的必要性: 数据安全性:技术世界并非总是完满的。零碎可能会蒙受故障、解体或蒙受攻打。在没有长久化的状况下,所有存储在内存中的数据在这些状况下都可能失落。长久化提供了一种机制,确保这些数据在产生故障后能够被复原。 例子: 设想一下你在电脑上工作了好几个小时,忽然停电了。如果你没有定期保留你的工作,那么你可能会失去所有的致力。数据库长久化就像定期保留你的文件,确保即便发生意外,你的数据也不会失落。 Redis 长久化的形式Redis 提供三种长久化的形式: 别离是 RDB(Redis Database Snapshot) 和 AOF(Append Only File)以及 混合长久化。 RDBRDB是什么?RDB 长久化形式是 Redis 将以后内存中的数据快照(snapshot)保留到硬盘的过程。换句话说,Redis 会创立一个代表某一时刻的数据集的磁盘文件。 例子: 设想一下相机的快门点击。每当你点击快门,你都会捕捉到那个特定时刻的场景。RDB的工作形式很类似,只不过它捕获的是数据的状态。 了解 RDB 的实质后,你可能会问,咱们如何生成这个快照呢?应用 SAVE 和 BGSAVE 命令即可。 RDB 生成图解 RDB 工作原理RDB 生成的流程图 步骤阐明: 1.触发RDB生成: 触发 RDB 文件的生成有以下两种形式: 手动触发:通过执行 SAVE 或 BGSAVE 命令。 主动触发:基于 Redis 配置文件中的 save 指令设置的条件。(默认是通过 BGSAVE 命令来触发的) ...

February 23, 2024 · 4 min · jiezi