基于多设计模式下的同步异步日志系统
基于多设计模式下的同步&异步日志系统
代码链接:https://github.com/Janonez/Log_System
1. 项目介绍
本项目主要实现一个日志系统, 其主要支持以下功能:
- 支持多级别日志消息
- 支持同步日志和异步日志
- 支持可靠写入日志到标准输出、文件以及滚动文件中
- 支持多线程程序并发写日志
- 支持扩展不同的日志落地目标地
2. 开发环境
- CentOS 7
- VSCode/vim
- g++/gdb
- Makefile
3. 核心技术
- 类层次设计(继承和多态的应用)
- C++11(多线程、auto、智能指针、右值引用等)
- 双缓冲区
- 生产消费模型
- 多线程
- 设计模式(单例、工厂、代理、模板等)
4. 日志系统介绍
4.1 为什么需要日志系统
- 生产环境的产品为了保证其稳定性及安全性是不允许开发人员附加调试器去排查问题, 可以借助日志系统来打印一些日志帮助开发人员解决问题,上线客户端的产品出现bug无法复现并解决, 可以借助日志系统打印日志并上传到服务端帮助开发人员进行分析
- 对于一些高频操作(如定时器、心跳包)在少量调试次数下可能无法触发我们想要的行为,通过断点的暂停方式,我们不得不重复操作几十次、上百次甚至更多,导致排查问题效率是非常低下, 可以借助打印日志的方式查问题。
- 在分布式、多线程/多进程代码中, 出现bug比较难以定位, 可以借助日志系统打印log帮助定位bug
- 帮助首次接触项目代码的新开发人员理解代码的运行流程
4.2 日志系统技术实现
日志系统的技术实现主要包括三种类型:
- 利用printf、std::cout等输出函数将日志信息打印到控制台
- 对于大型商业化项目, 为了方便排查问题,我们一般会将日志输出到文件或者是数据库系统方便
- 查询和分析日志, 主要分为同步日志和异步日志方式
4.2.1 同步写日志
同步日志是指当输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑语句,日志输出语句与程序的业务逻辑语句将在同一个线程运行。每次调用一次打印日志API就对应一次系统调用write写日志文件。
在高并发场景下,随着日志数量不断增加,同步日志系统容易产生系统瓶颈:
- 一方面,大量的日志打印陷入等量的write系统调用,有一定系统开销。
- 另一方面,使得打印日志的进程附带了大量同步的磁盘IO,影响程序性能。
4.2.2 异步写日志
异步日志是指在进行日志输出时,日志输出语句与业务逻辑语句并不是在同一个线程中运行,而是有专门的线程用于进行日志输出操作。业务线程只需要将日志放到一个内存缓冲区中不用等待即可继续执行后续业务逻辑(作为日志的生产者),而日志的落地操作交给单独的日志线程去完成(作为日志
的消费者), 这是一个典型的生产-消费模型。
这样做的好处是即使日志没有真的地完成输出也不会影响程序的主业务,可以提高程序的性能:
- 主线程调用日志打印接口成为非阻塞操作
- 同步的磁盘IO从主线程中剥离出来交给单独的线程完成
5. 日志系统框架设计
将一条消息,进行格式化成为指定格式的字符串后,写入到指定位置
本项目实现的是一个多日志器日志系统,主要实现的功能是让程序员能够轻松的将程序运行日志信息落地到指定的位置,且支持同步与异步两种方式的日志落地方式。
5.1 模块划分
- 日志等级模块:对输出日志的等级进行划分,以便于控制日志的输出,并提供等级枚举转字符串功能。
- 日志消息模块:中间存储日志输出所需的各项要素信息
- 日志消息格式化模块:设置日志输出格式,并提供对日志消息进行格式化功能。
- 日志消息落地模块:决定了日志的落地方向,可以是标准输出,也可以是日志文件,也可以滚动文件输出…
- 日志器模块:此模块是对以上几个模块的整合模块,用户通过日志器进行日志的输出,有效降低用户的使用难度。包含有:日志消息落地模块对象,日志消息格式化模块对象,日志输出等级
- 日志器管理模块:创建的所有日志器进行统一管理。并提供一个默认日志器提供标准输出的日志输出。
- 异步线程模块:实现对日志的异步输出功能,用户只需要将输出日志任务放入任务池,异步线程负责日志的落地输出功能,以此提供更加高效的非阻塞日志输出。
5.2 模块关系图
6. 代码设计
6.1 实用类设计
提前完成一些零碎的功能接口,以便于项目中会用到。
- 获取系统时间
- 判断文件是否存在
- 获取文件的所在目录路径
- 创建目录
6.2 日志等级类设计
定义出日志系统所包含的所有日志等级,分别为:
- UNKNOW:未知等级日志
- DEBUG:调试等级的日志
- INFO:提示等级的日志
- WARN:警告等级的日志
- ERROR:错误等级的日志
- FATAL:致命错误等级的日志
- OFF:关闭所有日志输出
每个项目都会设置一个默认的日志输出等级,只有输出的日志等级大于等于默认限制等级的时候才可以进行输出
提供一个接口,将对应等级的枚举,转换为一个对应的字符串,例如DEBUG -->> “DEBUG”
6.3 日志消息类设计
日志消息类主要是封装一条完整的日志消息所需的内容,其中包括日志输出时间、日志等级、日志源文件名称、源代码行号、线程ID、具体的日志信息等内容。
6.4 日志输出格式化类设计
日志格式化(Formatter)类主要负责格式化日志消息,组织成为指定格式的字符串。其主要包含以下内容:
-
格式化字符串
%d 日期
%T 缩进
%t 线程id
%p 日志级别
%c 日志器名称
%f 文件名
%l 行号
%m 日志消息
%n 换行 -
格式化子项数组
MsgFormatItem :有效日志数据
LevelFormatItem :日志等级
NameFormatItem :日志器名称
ThreadFormatItem :线程ID
TimeFormatItem :时间戳
CFileFormatItem :文件名
CLineFormatItem :行号
TabFormatItem :制表符缩进
NLineFormatItem :换行
OtherFormatItem :非格式化的原始字符串
6.5 日志落地(LogSink)类设计(简单工厂模式)
日志落地类主要负责将格式化完成后的日志消息字符串,输出到指定位置。
目前实现了三个不同方向上的日志落地:
- 标准输出:StdoutSink
- 固定文件:FileSink
- 滚动文件:RollSink
6.6 日志器类(Logger)设计(建造者模式)
日志器主要是对前面所有模块进行整合,向外提供接口完成不同等级的日志输出
- 管理的成员:
格式化模块对象(不同输出等级的日志)
落地模块对象数组(一个日志器可能会向多个位置进行日志输出)
默认的日志输出限制等级(大于等于限制等级的日志才能输出)
互斥锁(保证日志输出是线程安全的,不会出现交叉日志)
日志器名称(日志器的唯一表示,以便于查找) - 实现:
抽象Logger基类(派生出同步日志器类 & 异步日志器类),两个不同的日志器在日志的落地方式上有所不同:
同步日志器:直接对日志消息进行输出
异步日志器:将日志消息放入缓冲区,由异步线程进行输出
使用建造者模式来建造日志器,不要让用户直接去构造日志器,简化用户操作
-
抽象一个日志器建造者类
设置日志器类型
将不同类型日志器的创建放到同一个日志器建造者类中完成
-
派生出具体的建造者类 – 局部日志器的建造者 & 全局的日志器建造者
6.7 双缓冲区异步任务处理器(AsyncLooper)设计
设计思想:异步处理线程 + 数据池
使用者将需要完成的任务添加到任务池中,由异步线程来完成任务的实际执行操作。
任务池的设计思想:双缓冲区阻塞数据池
优势:避免了空间的频繁申请释放,且尽可能的减少了生产者与消费者之间锁冲突的概率,提高了任务处理效率。
在任务池的设计中,有很多备选方案,比如循环队列等等,但是不管是哪一种都会涉及到锁冲突的情况,因为在生产者与消费者模型中,任何两个角色之间都具有互斥关系,因此每一次的任务添加与取出都有可能涉及锁的冲突,而双缓冲区不同,双缓冲区是处理器将一个缓冲区中的任务全部处理完毕
后,然后交换两个缓冲区,重新对新的缓冲区中的任务进行处理,虽然同时多线程写入也会冲突,但是冲突并不会像每次只处理一条的时候频繁(减少了生产者与消费者之间的锁冲突),且不涉及到空间的频繁申请释放所带来的消耗。
单个缓冲区的设计:直接存放格式化后的日志消息字符串,这样做的优点是:
- 减少了LogMsg对象频繁的构造的消耗
- 可以针对缓冲区中的日志消息,一次性进行IO操作,减少IO次数,提高效率
6.8 异步日志器(AsyncLogger)设计
异步日志器类继承自日志器类, 并在同步日志器类上拓展了异步消息处理器。
- 异步工作使用双缓冲区
外界将任务数据添加到输入缓冲区中。异步线程对处理缓冲区中的数据进行处理,如果处理缓冲区中没有数据就交换缓冲区 - 回调函数:针对缓冲区中数据的处理接口,外界传入一个函数,告诉异步工作器如何处理
6.9 单例日志器管理类设计(单例模式)
日志的输出,我们希望能够在任意位置都可以进行,但是当我们创建了一个日志器之后,就会受到日志器所在作用域的访问属性限制。
为了突破访问区域的限制,我们创建一个日志器管理类,且这个类是一个单例类,这样的话,我们就可以在任意位置来通过管理器单例获取到指定的日志器来进行日志输出了。
单例管理器创建的时候,默认创建一个用于标准输出的打印日志器,让用户再不创建任何日志器的情况下,也能进行标准输出的打印,方便用户使用。
基于单例日志器管理器的设计思想,我们对于日志器建造者类进行继承,继承出一个全局日志器建造者类,实现一个日志器在创建完毕后,直接将其添加到单例的日志器管理器中,以便于能够在任何位置通过日志器名称能够获取到指定的日志器进行日志输出。
6.10 日志宏&全局接口设计(代理模式)
提供全局的日志器获取接口。
使用代理模式通过全局函数或宏函数来代理Logger类的log、debug、info、warn、error、fatal等接口,以便于控制源码文件名称和行号的输出控制,简化用户操作。
当仅需标准输出日志的时候可以通过主日志器来打印日志。 且操作时只需要通过宏函数直接进行输出即可。
7. 性能测试
下面对日志系统做一个性能测试,测试一下平均每秒能打印多少条日志消息到文件。
主要的测试方法是:每秒能打印日志数 = 打印日志条数 / 总的打印日志消耗时间
主要测试要素:同步/异步 & 单线程/多线程
- 100w+条指定长度的日志输出所耗时间
- 每秒可以输出多少条日志
- 每秒可以输出多少MB日志
测试环境:
阿里云轻量应用服务器
CPU:2核 CPU
RAM:2GB
ROM:50GB ESSD
OS:CentOS 7.6
[Janonez@linux bench]$ ./bench
// sync_logger - 同步单线程
测试日志: 1000000 条, 总大小: 97656KB线程[0]: 输出日志数量: 1000000, 耗时: 1.8201s总耗时: 1.8201 s每秒输出日志数量: 549420 条每秒输出日志大小: 53654KB// async_logger - 异步单线程
测试日志: 1000000 条, 总大小: 97656KB线程[0]: 输出日志数量: 1000000, 耗时: 1.67192s总耗时: 1.67192 s每秒输出日志数量: 598113 条每秒输出日志大小: 58409KB[Janonez@linux bench]$ ./bench
// sync_logger - 同步多线程
测试日志: 1000000 条, 总大小: 97656KB线程[2]: 输出日志数量: 333333, 耗时: 1.57987s线程[1]: 输出日志数量: 333333, 耗时: 1.69374s线程[0]: 输出日志数量: 333333, 耗时: 1.72153s总耗时: 1.72153 s每秒输出日志数量: 580876 条每秒输出日志大小: 56726KB// async_logger - 异步多线程
测试日志: 1000000 条, 总大小: 97656KB线程[0]: 输出日志数量: 333333, 耗时: 1.14526s线程[2]: 输出日志数量: 333333, 耗时: 1.18942s线程[1]: 输出日志数量: 333333, 耗时: 1.26282s总耗时: 1.26282 s每秒输出日志数量: 791876 条每秒输出日志大小: 77331KB
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/b9b4348711643afeefa94263e6e40232.jpeg)
基于多设计模式下的同步异步日志系统
基于多设计模式下的同步&异步日志系统 代码链接:https://github.com/Janonez/Log_System 1. 项目介绍 本项目主要实现一个日志系统, 其主要支持以下功能: 支持多级别日志消息支持同步日志和异步日志支持可靠写入日志到标准输出、文件…...
![](https://img-blog.csdnimg.cn/625909fb19164ff689087ef793f5a803.png)
API接口与电商平台之间的联系,采集京东平台数据按关键字搜索商品接口示例
关键字搜索商品的重要性: 1.引入精准流量 关键词第一个也是最重要的作用就是为我们宝贝引进精准的流量,这一作用无论是在自然搜索中还是直通车中都是一样的。 第一步关乎的是我们宝贝的展现,而第二步用户是否会点进我们的宝贝,…...
![](https://www.ngui.cc/images/no-images.jpg)
代码随想录day41|343. 整数拆分96. 不同的二叉搜索树
343. 整数拆分 class Solution:def integerBreak(self, n: int) -> int:dp [0] *(n1)dp[2]1if n <3:return dp[n]for i in range(3,n1):for j in range(1,n):dp[i]max(j*(i-j),j*dp[i-j],dp[i])return dp[n] 96. 不同的二叉搜索树 class Solution:def numTrees(self, …...
![](https://www.ngui.cc/images/no-images.jpg)
Less常用内置函数
1,类型函数 isnumber(value) - 判断是否为数字isstring(value) - 判断是否为字符串isurl(value) - 判断是否为urliscolor(value) - 判断是否为颜色isunit(value, unit) - 判断value值是否为指定单位 示例: isnumber(12); // true isnumber(#333); // f…...
![](https://img-blog.csdnimg.cn/6cf6152ae7a1472e97ab9454b8943dc1.png)
pdf转换成图片转换器在线怎么转?pdf转换成图片具体方法介绍
很多用户们都是比较喜欢使用pdf文档的,由于这种文件格式的便携性非常高,所以广泛的应用于工作和学习领域,再加上pdf文档可以随意转换成为其他的文件格式,更是让pdf文档受到了更多用户们的欢迎,那么pdf转换成图片转换器…...
![](https://www.ngui.cc/images/no-images.jpg)
JavaScript动态设置浏览器可视区域元素的文字颜色、监听滚动条、querySelectorAll、getBoundingClientRect
文章目录 前言htmlJavaScriptquerySelectorAllgetBoundingClientRect 前言 当元素出现在浏览器可视区域时给元素设置颜色等其他操作,比如当元素进入浏览器可视区域时,设置元素进入动画。 html <div id"idBox" class"box"><…...
![](https://img-blog.csdnimg.cn/img_convert/e18ab3db5d8bf3b16aa76f38fbe656af.png)
意向客户的信息获取到底是怎样的,快来get一下
客户信息获取技术真的可以为企业提供精准客源吗?这个渠道到底安不安全,技术到底成不成熟?效果到底如何?下面简单的和大家分析一下。 客户信息获取技术是怎样的 手机采集引流方面,上量不精准,精准不上量的说…...
![](https://www.ngui.cc/images/no-images.jpg)
自动化测试常用脚本语言有哪些?
在自动化测试中,常用的脚本语言包括: 1. Python:Python是一个简洁、易读且功能强大的脚本语言,广泛应用于自动化测试领域。它具有丰富的测试框架和库,可以用于Web、移动应用和API等各种类型的测试。 2. Java࿱…...
![](https://www.ngui.cc/images/no-images.jpg)
mapreduce 的工作原理以及 hdfs 上传文件的流程
推荐两篇博文 mapreduce 的工作原理: 图文详解 MapReduce 工作流程_mapreduce工作流程_Shockang的博客-CSDN博客 hdfs 上传文件的流程 HDFS原理 - 知乎...
![](https://www.ngui.cc/images/no-images.jpg)
Ubuntu22.04安装ROS2
Ubuntu22.04安装ROS2 Excerpt ROS2官方文档 ROS2清华镜像站sudo apt update sudo apt upgrade locale # check for UTF-8 sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALLe… ROS2官方文档 ROS2清华镜像站…...
![](https://img-blog.csdnimg.cn/1c4c85df70f24b51bef8c65cdbae3fa7.png)
uniapp - 倒计时组件-优化循环时间倒计时
使用定时器的规避方法 为了避免定时器误差导致倒计时计算错误,可以采用一些规避方法,比如将倒计时被中断时的剩余时间记录下来,重新开启定时器时再将这个剩余时间加到新的计算中。同时,为了避免定时器延迟,可以在每次执…...
![](https://www.ngui.cc/images/no-images.jpg)
java 实现访问者模式
访问者模式是一种行为设计模式,它允许您在不修改对象结构的情况下,向对象结构中的元素添加新的操作。这通常用于解决对象结构中元素类型多变,但操作类型相对稳定的问题。在访问者模式中,我们有一个访问者接口和多个具体的元素类&a…...
![](https://img-blog.csdnimg.cn/33e24602022840ceb2b4311d27274d3a.png)
JDK源码剖析之PriorityQueue优先级队列
写在前面 版本信息: JDK1.8 PriorityQueue介绍 在数据结构中,队列分为FIFO、LIFO 两种模型,分别为先进先出,后进后出、先进后出,后进先出(栈) 而一切数据结构都是基于数组或者是链表实现。 在…...
![](https://img-blog.csdnimg.cn/img_convert/8705738a76e4a0b774eb9ba21ce9a3b4.png)
TSINGSEE青犀AI视频分析/边缘计算/AI算法·人脸识别功能——多场景高效运用
旭帆科技AI智能分析网关可提供海量算法供应,涵盖目标监测、分析、抓拍、动作分析、AI识别等,可应用于各行各业的视觉场景中。同时针对小众化场景可快速定制AI算法,主动适配大厂近百款芯片,打通云/边/端灵活部署,算法一…...
![](https://www.ngui.cc/images/no-images.jpg)
力扣(LeetCode)算法_C++——最大连续 1 的个数 III
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。 示例 1: 输入:nums [1,1,1,0,0,0,1,1,1,1,0], K 2 输出:6 解释:[1,1,1,0,0,1,1,1,1,1,1] 粗体数字…...
![](https://img-blog.csdnimg.cn/4e78b16d6861453e97db35c44cf2c215.png)
23062C++QT day2
封装一个结构体,结构体中包含一个私有数组,用来存放学生的成绩,包含一个私有变量,用来记录学生个数, 提供一个公有成员函数,void setNum(int num)用于设置学生个数 提供一个公有成员函数:void…...
![](https://img-blog.csdnimg.cn/abe0f19768154f95af156729d9fea0bc.png)
React三属性之:props
作用 将父组件的参数传递给子组件 父组件 import ./App.css; import React from react; import PropsTest from ./pages/propsTest class App extends React.Component{render(){return(<div><h2>App组件</h2><PropsTest obj{{name:王惊涛,age:27}}>…...
![](https://img-blog.csdnimg.cn/381e278b61a949d9bbbc23bcfad93b38.png)
大数据安全 | (一)介绍
目录 📚大数据安全 🐇大数据安全内涵 🐇大数据安全威胁 🐇保障大数据安全 ⭐️采集环节安全技术 ⭐️存储环节安全技术 ⭐️挖掘环节安全技术 ⭐️发布环节安全技术 🐇大数据用于安全 📚隐私及其…...
![](https://www.ngui.cc/images/no-images.jpg)
软件工程的概念及其重要性
软件工程是指将工程原理和方法应用于软件开发过程的学科,涉及软件的设计、开发、测试、维护和管理等各个阶段。它旨在提高软件开发的效率和质量,并确保软件满足用户的需求和预期。 软件工程的重要性体现在以下几个方面: 提高开发效率&#x…...
![](https://img-blog.csdnimg.cn/79d2bce6f6084624a10e8b7e49babd4c.png)
[足式机器人]Part3 变分法Ch01-2 数学预备知识——【读书笔记】
本文仅供学习使用 本文参考: 《变分法基础-第三版》老大中 《变分学讲义》张恭庆 《Calculus of Variations of Optimal Control Theory》-变分法和最优控制论-Daneil Liberzon Ch01-2 数学基础-预备知识1 1.3.2 向量场的通量和散度1.3.3 高斯定理与格林公式 1.3.2 …...
![](https://img-blog.csdnimg.cn/e68159db000e404a9e972412718728e2.png)
【嵌入式开发 Linux 常用命令系列 7.1 -- awk 过滤列中含有特定字符的行】
文章目录 awk 过滤列中字符串 上篇文章:嵌入式开发 Linux 常用命令系列 7 – awk 常用方法详细介绍 awk 过滤列中字符串 cat test.log | awk -F $31 {print $0}说明: -F 以什么分隔列,这里是以空格为分隔符;$3代表第3列;$3…...
![](https://img-blog.csdnimg.cn/99411a2e01f64456b912857473a5925c.gif#pic_center)
前端(十六)——Web应用的安全性研究
🙂博主:小猫娃来啦 🙂文章核心:Web应用的安全性研究 文章目录 概述常见前端安全漏洞XSS(跨站脚本攻击)CSRF(跨站请求伪造) 点击劫持安全性验证与授权用户身份验证授权与权限管理 安全…...
![](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://www.learnfk.com/guide/images/wuya.png)
无涯教程-JavaScript - BIN2HEX函数
描述 BIN2HEX函数将二进制数转换为十六进制。 语法 BIN2HEX (number, [places])争论 Argument描述Required/Optionalnumber 您要转换的二进制数。 数字不能超过10个字符(10位)。数字的最高有效位是符号位。其余的9位是幅度位。 负数使用二进制补码表示。 Requiredplaces 要…...
![](https://img-blog.csdnimg.cn/810b586d4a224e1891f0694214d4d0aa.png)
Kafka环境搭建与相关启动命令
一、Kafka环境搭建 点击下载kafka_2.11-2.3.1.tgz文件链接 1、上传kafka_2.11-2.3.1.tgz,解压kafka_2.11-2.3.1.tgz,得到kafka_2.11-2.3.1文件夹 1)上传 #使用mobaxterm将 kafka_2.11-2.3.1.tgz 传入tools文件夹 #用下面代码进入tools文件…...
![](https://img-blog.csdnimg.cn/e8b351e183e04aac98ec3721b3876148.png)
【C++】类的封装 ② ( 封装最基本的表层概念 | 类对象作为参数传递的几种情况 )
文章目录 一、类的封装 : 将数据和方法封装到一个类中1、封装最基本的表层概念2、代码分析 - 基本封装3、代码分析 - 类对象作为参数传递的几种情况 ( 指针 / 引用 / 直接 )4、完整代码示例 一、类的封装 : 将数据和方法封装到一个类中 1、封装最基本的表层概念 将数据和方法封…...
![](https://img-blog.csdnimg.cn/3ba2d8f30e9e461c87d2d05744240ada.png)
Linux上安装FTP
1、登录FTP,执行安装命令 yum -y install vsftpd 2、启动FTP服务器,设置开启自启动 systemctl enable vsftpd.service systemctl start vsftpd.service systemctl status vsftpd.service #查看状态, 显示active说明FTP启动成功 3、修改FTP配置文件/et…...
![](https://www.ngui.cc/images/no-images.jpg)
C/C++使用GDAL库编程窍门之——通用可移植性库(Common Portability Library, CPL)
C/C使用GDAL库编程窍门之——通用可移植性库(Common Portability Library, CPL) CPL简介 GDAL全称地理空间数据抽象库(Geospatial Data Abstraction Library),是一个强大的地理栅格空间数据转换库,支持众…...
![](https://www.ngui.cc/images/no-images.jpg)
Linux container_of() 宏定义
container_of 宏 今天遇到了一段这样的代码,大致意思是 通过该struct结构体变量的成员的地址来反推该struct结构体变量的地址 并且用到了内核的宏,container_of() static inline struct nova_inode_info *NOVA_I(struct inode *inode) {return container…...
![](https://www.ngui.cc/images/no-images.jpg)
详解python中的序列类型---列表list
概述 列表类型是包含0个或多个元素的有序序列,属于序列类型。列表可以进行元素的增加、删除、替换、查找等操作。列表没有长度限制,无素类型可以不同,不需要预定长度。 列表类型用中括号[]表示,也可以通过list(x)函数将集合或字…...
![](https://img-blog.csdnimg.cn/img_convert/cb43bf57fd3effe1cafd9dbff45621ea.webp?x-oss-process=image/format,png)
Unity 引擎中国版 “团结引擎” 发布
导读Unity 官方宣布,Unity 中国正式推出 Unity 中国版引擎 —— 团结引擎,同时也开启了 Unity 中国本土化进程的全新篇章。作为推动团结引擎落地的核心人物,Unity 中国 CEO 张俊波称致力于将其打造为一款更懂中国开发者的引擎。 团结引擎以 U…...
![](https://img-blog.csdnimg.cn/img_convert/8293885ad8fc50e955edd828d90a3b23.png)
哪些网站开发/友情链接交换平台源码
桔妹导读:随着计算机技术和工程架构的发展,微服务变得越来越热。如今,绝大多数服务都处于分布式环境中,其中,数据一致性是我们一直关注的重点。分布式锁到底是什么?经过了哪些发展演进?工程上有…...
![](/images/no-images.jpg)
网站开发主要框架 后端/网站优化推广教程
摘要:本文所讲述的内容,为ElasticSearch(以下简称ES)全文搜索引擎在实际大数据项目的应用;ES的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。ES 是 Lucene 的…...
![](https://img2018.cnblogs.com/blog/1467309/201812/1467309-20181203193453037-41934405.png)
政府网站站群建设方案/搜索引擎技巧
Spring-Boot-2.0.0-M1版本将默认的数据库连接池从tomcat jdbc pool改为了hikari,这里主要研究下hikari的默认配置 0. 创建Spring Boot项目,选中 Web、MySQL、JDBC 依赖 1. 启动类默认加载了DataSourceAutoConfiguration,默认数据源是HikariD…...
![](/images/no-images.jpg)
免费的ppt网站推荐/视频网站推广
在使用spring创建bean的时候需要在指定bean的生命周期,bean的声明周期有一下几种: singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例prototype表示每次获得bean都会生成一个新的对象request表示在一次http请…...
![](https://img-blog.csdnimg.cn/img_convert/f222166c6a8d9d2a8b6d23f90f7d1663.png)
phpcms律师网站源码/免费的app推广平台
题库来源:安全生产模拟考试一点通公众号小程序 2022安全员-A证试题是安全员-A证模拟考试题库的多种练习模式!2022年安全员-A证特种作业证考试题库及答案依据安全员-A证新考试大纲。安全员-A证全部考试题库随时根据安全生产模拟考试一点通提高考试通过率…...
![](/images/no-images.jpg)
网站建设的过程包括几个阶段/营销策划与运营公司
一、mysql数据库日常操作。 1.启动mysql:/etc/init.d/mysql start (前面为mysql的安装路径) 2.重启mysql: /etc/init.d/mysql restart (前面为mysql的安装路径) 3.关闭mysql: /etc/init.d/mysql stop(前面为mysql的安装路径) …...