从alpine编译nginx的docker镜像
因为需要接入nginx监控,用的是vts模块,原生nginx并没有包含该模块,原本想着用别人已经编译好的, 但是一想后期可能还需要加入其他的模块,所以还是自己编译一个。
下面说一下具体的步骤。
编写dockerfile文件此处用的几个主要软件版本:
alpine: 3.17
nginx: 1.22.1
nginx-module-vts: 0.2.1
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748FROM alpine:3.17ENV NGINX_VERSION nginx-1.22.1RUN echo https://mirrors.aliyun.com/alpine/v3.17/main/ > /etc/apk/repositories && \ echo https://mirrors.aliyun.com/alpine/v3.17/community/ >> /etc/apk/repositoriesRUN ...
hexo主题使用css添加网格背景
给hexo的博客添加一个网格背景, 此处不想使用图片, 而是直接使用css来实现,效果图如下:
css文件内容如下(文件名background.css):
12345body { background:white; background-image:linear-gradient(90deg,rgba(241,243,244,1) 10%,transparent 0),linear-gradient(rgba(241,243,244,1) 10%,transparent 0); background-size:15px 15px;}
为了各个hexo主题都能通用, 此处使用hexo提供的注入功能将css注入到博客中。
在博客根目录下新建一个scripts文件夹, 然后在该文件下新建一个js文件(命名随便都行),复制如下代码:
1hexo.extend.injector.register('head_end','<link rel="stylesheet" type="text/css&quo ...
live555搭建流视频服务播放视频文件
为了方便,使用docker搭建,用的是docker hub上使用人数最多的一个镜像, docker-compose.yml文件内容如下所示:
12345678910version: "3"services: live555: image: vimagick/live555 container_name: live555 restart: always ports: - 554:554 volumes: - ${PWD}/data:/data
视频文件放在当前目录的data文件夹下, 然后使用vlc播放rtsp流地址测试一下, rtsp地址:
1rtsp://ip:554/demo.264
JVM内存分配机制介绍
本文针对的是hotspot虚拟机, jdk版本1.8的虚拟机进行介绍。
程序计数器线程私有,可以看做是当前线程所执行的字节码的行号,用于下一次线程切换的时候虚拟机定位到上一次执行的位置。
虚拟机栈在一个时间点,只会有一个活动的栈帧,通常叫作当前帧,方法所在的类叫作当前类。
如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,成为新的当前帧,一直到它返回结果或者执行结束。JVM直接对Java栈的操作只有两个,就是对栈帧的压栈和出栈。
总结几点如下:
线程私有,生命周期与线程相同。描述的是方法执行的内存模型。
进入方法时对应入栈,方法结束的时候对应出栈。
该区域存储着局部变量,操作数,方法出口等信息。
方法区
线程共享。用于存储类信息、常量池、静态变量、JIT编译后的代码等数据。具体放在哪里,不同的实现可以放在不同的地方。
一般情况可以理解成class文件在内存中的存放位置。
在1.7和1.8之后的实现逻辑有所不同。
由于该区域大小一般较小,所以不会对该区域进行垃圾回收。所以在1.7之前的版本,有可能会因为字符串常量池过大导致该区域内存溢出(Permgen space ...
jenkins使用流水线打包springboot和vue镜像
使用jenkins的流水线功能,可以很方便的知道各个步骤的执行进度和所用时间,还是比较方便的。
在流水线中可以使用docker进行打包, 这样就可以很方便的使用任何docker镜像,而不需要安装对应的环境。
本文要实现的目的如下:
从git仓库拉取代码,并允许指定分支或tag
jenkins编译代码
构建镜像
push镜像到远程仓库(此处是阿里云仓库)
使用前准备本文的jenkins本身也是docker安装的, 为了直接使用宿主机的docker,需要在安装jenkins容器的时候将宿主机的docker映射到jenkins容器中,比如使用docker-compose时其部分配置如下:
12- /var/run/docker.sock:/var/run/docker.sock- /usr/bin/docker:/usr/bin/docker
Java镜像构建springboot工程需要有一个springboot工程的仓库,并且在项目的根文件下新建一个Dockerfile文件, 内容如下:
123456FROM openjdk:17RUN echo "Asia/Shan ...
使用prometheus监控clickhouse
较新版本的clickhouse内部已经支持暴露监控数据给prometheus, 所以此处就不用另外部署clickhouse-exporter服务来获取监控数据。
clickhouse配置修改clickhouse的配置文件config.xml, 将prometheus这一项原先的注释放开,使其生效。
官方文档路径:https://clickhouse.com/docs/en/operations/server-configuration-parameters/settings/#server_configuration_parameters-prometheus
12345678<prometheus> <endpoint>/metrics</endpoint> <port>9363</port> <metrics>true</metrics> <events>true</events> <asynchronous_metrics>true ...
克服自己
要克服自己的缺陷,打败自己, 这句话说起来容易做起来却是很难。
你会因为惯性去做使自己舒适的事,这样就容易在舒适的道路上越走越远,也就与你自己制定的目标相去甚远。
如此,要怎样克服自己?
我觉的有如下几点需要注意。
首先不要给自己过于遥远的目标,这样你是一定无法完成的,就会产生懈怠心理。
其次,对于目标一定要检验成果,并且记录下来,不要欺骗自己。
共勉之!
微服务架构中关于事务的一些思考
分布式事务 指的是当事务的操作分布在不同的节点上时, 需要保证事务的ACID特性。 其中最重要的一点是要保证在各个节点上的事务要么同时成功,要么同时失败。
分布式事务的解决方案有多种,下面对几种常见的进行一一说明。
2PC2PC, Two-phase Commit 。两阶段提交,通过引入协调者(Coordinator)来协调所有参与者的行为,并最终决定这些参与者是否要真正执行事务。
两个阶段分别如下:
第一阶段:准备阶段。由协调者询问各个参与节点事务是否执行成功,参与节点返回事务执行结果。参与节点收到通知之后,会进行准备操作,例如执行insert(此时并未commit),准备完成之后会告诉协调节点自己已经准备完成。
第二阶段:提交阶段。协调节点在收到所有参与节点都执行成功之后,就会通知所有节点进行提交操作。若任一节点执行失败,协调节点则会通知所有参与节点回滚数据。
主要缺点如下:
阻塞。 需要等待所有参与者确认OK之后才能commit, 其处理的时间取决于处理事务最慢的那个参与节点。所以不适合并发高的场景。
单点故障。 特别是对协调节点的依赖很大,若协调节点发生故障,则整个事务都 ...
drone和gitea集成以及hexo博客的自动部署
未完待续!
目的是为了实现hexo博客的自动部署, 每次push完之后, 触发drone ci自动进行部署。
选用drone的原因还是因为轻量, 且功能够用,如果用其他的CI工具,比如jenkins,我这小小的VPS部署服务一多,就扛不住了。
本文中drone是和gitea进行集成的, 如果要和其他仓库集成, 参考官方文档即可:https://docs.drone.io/
部署服务还是通过docker来进行。
准备工作登录gitea, 进入设置->应用, 新建一个给drone用的OAuth2授权
注意, 重定向URI(Redirect URI)是你的drone服务的域名加上login。
生成授权之后, 会得到一个客户端ID和客户端秘钥, 记下来, 后面会用到。
drone搭建本文在部署的时候, 是将drone和gitea进行集成,
drone的服务分为两部分:
drone-server
drone-runner-docker
本人将这两个服务都部署在同一个docker-compose.yml中,同时数据库还是连接的一个单独的mysql容器服务,所以需要先创建数据库, 命令 ...
记录服务异常重启导致clickhouse启动失败
测试环境中某个clickhouse实例由于意外断电而终止,重新启动报错,报错的关键信息 DB::ParsingException: Cannot parse input: expected ‘columns format version: 1\n’ at end of stream
其中报错的日志如下:
1{} <Error> auto DB::MergeTreeData::loadDataParts(bool)::(anonymous class)::operator()() const: Code: 27. DB::ParsingException: Cannot parse input: expected 'columns format version: 1\n' at end of stream. (CANNOT_PARSE_INPUT_ASSERTION_FAILED), Stack trace (when copying this message, always include the lines below):
可以搜 ...