标签: Programmatic
Redis RediSearch
RediSearch 是一个高性能的全文搜索引擎,它可以作为一个 Redis Module(扩展模块)运行在 Redis 服务器上。
RediSearch

企业架构分布式系统
分布式系统
开发了几年的分布式系统,对其原理模模糊糊。大量的时间在研究场景下解决方案。并未深入总结过。本文梳理个人对分布式的认知理解。
-
在没有系统学习分布式相关知识的情况,通常选择针对局部场景需求进行认知下
局部最优解决。处理问题也没有十足的把握,在系统稳定性上只能通过case by case的方式处理。 -
解决单机性能瓶颈。
-
解决数据增加运维成本。

编程式权限设计
背景
权限管理是一个几乎所有大中型 B 端系统都会涉及的重要组成部分,其目的是对整个系统进行权限控制,避免造成误操作及数据泄露等风险问题。
权限与权限管理
名词定义
权限相关的基本概念:
- 权限:用户可操作行为的最小单位。
- 用户:每个用户都有唯一标识,并被授予一个或多个角色。
- 角色:由不同的权限组合而成,最终分配给具体用户。
- 权限管理:控制用户的权限,只能访问授权内容。
SpringBoot MyBatis 批量
开发过程中经常会出现批量写入数据库的操作,特别是后台系统,在导入数据的场景下会对表性能造成一定影响。
Mybatis-ONE-SQL
SQL插入主要使用INSERT语句,有两种常见的用法。
逐条插入
- 如果插入的记录过多,比如大于20条记录,性能损耗非常严重。
INSERT INTO `table_data` ('field1','field2') VALUES ('data1','data2');
SpringBoot 测试Mock
SpringBoot测试解决方案

-
mock
- Mock 的意思是模拟,它可以用来对系统、组件或类进行隔离。
- 验证组件级别正确性的一大难点在于关于组件与组件之间的依赖关系,这里就需要引出测试领域非常重要的一个概念,即 Mock(模拟)。

-
mvc-mock 测试Controller
-
service-mock 测试 Service
-
repository-mock 测试 Data
-
remote-mock 测试 远程接口
SpringBoot Redis布隆过滤器
Redis 中不能直接使用布隆过滤器,Redis 4.0 版本之后提供的 modules(扩展模块)
布隆过滤器的原理
- 数据结构使用一位的数组,每次存储键值的时候,不是直接把数据存储在数据结构中。而是经过hash运算。将此元素的 hash 值均匀的存储在位数组中。把这些位置设置成 1 就完成了添加操作。
- 判断元素是否存在时,经过运算判断对应的位置是否为全部1即可。因此布隆过滤器查询此值存在时,此值不一定存在,但查询此值不存在时,此值一定不存在。
- 但是存在一定的误差,并且当位数组存储值比较稀疏的时候,查询的准确率越高,而当位数组存储的值越来越多时,误差也会增大。
CentOS7 Jenkins 部署
记录最近在Centos7上面部署jenkens。安装的方法有很多,下面采用最简单的方式安装。
参考文献
- 在线文档 https://jenkins.io/doc/
- 名词解释:
- CI
jenkins 是一个协调者的身份,管理和协调了代码库,代码仓库,代码运行环境等。
jenkins 简介
Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。持续集成(CI)已成为当前许多软件开发团队在整个软件开发生命周期内侧重于保证代码质量的常见做法。它是一种实践,旨在缓和和稳固软件的构建过程。并且能够帮助您的开发团队应对如下挑战:
SpringBoot WebClient
WebClient
Spring 有两个web客户端的实现,一个是RestTemplate另一个是spring5的响应代替WebClient。
WebClient是一个以Reactive方式处理HTTP请求的非阻塞客户端。
-
RestTemplate是阻塞客户端
- 它基于thread-pre-requset模型。
- 这意味着线程将阻塞,直到 Web 客户端收到响应。阻塞代码的问题是由于每个线程消耗了一些内存和 CPU 周期。当出现慢速请求的时候,等待结果的线程会堆积起来,将导致创建更多的线程、消耗更多的资源。频繁切换CPU资源也会降低性能。
-
WebClient是异步、非阻塞的方案。
-
WebClient将为每个事件创建类似于“任务”的东西。在幕后,Reactive 框架会将这些“任务”排队并仅在适当的响应可用时执行它们。
-
WebClient是Spring WebFlux库的一部分。因此,我们还可以使用具有反应类型(Mono和Flux的功能性、流畅的 API 作为声明性组合来编写客户端代码。
-
底层支持的库
- Reactor Netty - ReactorClientHttpConnector
- Jetty ReactiveStream HttpClient - JettyHttpConnector
-
-
关于IDEA开启 Reactive Streams DEBUG
Docker Drone 部署
之前都是用jenkins+gitee 做的CI方案,发现朋友在使用Drone构建。运行资源占用比较小。适合个人做CI。
Drone
Drone是一款基于容器技术的持续集成工具,使用简单的YAML配置文件即可完成复杂的自动化构建、测试、部署任务,在Github上已经有22K+Star。
SpringBoot MyBatis
数据审计
部分业务需要记录用户对操作行为,如果给每张表都做一个记录表,感觉冗余数据太多了。所以采用审计表存储相关日志信息。
实现方案
基于Spring Aop 织入方式对关键方法进行拦截,也可以通过方法进行拦截。
- 基于注解,在方法上织入。
- 基于普通方法,在业务逻辑中进行调用。
- 批量写入、延时写入数据库可能会出现短时间部分数据的丢失,但是频繁写入会导致Mysql资源占用过多。
- 使用java.util.concurrent.ConcurrentLinkedQueue 作为消费列队。每次最多消费消费10条日志记录批量写入数据库。
- 在审计信息中添加业务执行链路标识、执行用户标识。方便排查问题。
- 基于MDC记录链路标识。
SpringBoot Redisson
Redisson
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(
BitSet,Set,Multimap,SortedSet,Map,List,Queue,BlockingQueue,Deque,BlockingDeque,Semaphore,Lock,AtomicLong,CountDownLatch,Publish / Subscribe,Bloom filter,Remote service,Spring cache,Executor service,Live Object service,Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。
Java Netty
Netty是一款用于快速开发高性能的网络应用程序的Java框架,正是因为有 Netty 的存在,网络编程领域 Java 才得以与 C++ 并肩而立。
- Netty 官网给出了有关 Netty 的整体功能模块结构

- Core核心层
提供底层网络通信抽象和实现,其中包括了可扩展的时间模型、通信API、支持零拷贝的buf等。
Redis 扫描
Scan
游标迭代器
大于 2.8.0 版本可用。
**时间复杂度:**每次调用 O(1)。O(N) 用于完整的迭代,包括足够的命令调用以使光标返回 0。N 是集合内的元素数。
-
在 Redis 2.8 之前,我们只能使用 keys 命令来查询我们想要的数据,但这个命令存在两个缺点:
-
此命令没有分页功能,我们只能一次性查询出所有符合条件的 key 值,如果查询结果非常巨大,那么得到的输出信息也会非常多。
-
keys 命令是遍历查询,因此它的查询时间复杂度是 o(n),所以数据量越大查询时间就越长。
-
Scan:用于检索当前数据库中所有数据。
-
HScan:用于检索哈希类型的数据。
-
SScan:用于检索集合类型中的数据。
-
ZScan:由于检索有序集合中的数据。
CentOS7 Jenkins本地部署分级
整理下Jenkins本地部署程序的过程。
-
在开发阶段,许多编译工具会将我们的源码编译可使用的文件。例如
vue-cli的项目会被webpack打包编译为浏览器的文件,Java项目会被编译为.class/jar文件以供服务器使用。-
开发人员将源代码,经过编译、压缩等一系列流程打包
-
上传到服务器。
-
在服务器将编译后的文件,手动可用的容器服务内(例如
Nginx,Tomcat,Apache等服务)
-
Mac 安装 Neo4j Jupyter
准备学习下neo4j记录在mac下安装neo4j的坑。
neo4j官网网站下载失败
国内只能从镜像地址下载
http://doc.we-yun.com:1008/
配置jdk11
可以查看我上面内容实用Jenv管理多个版本。
启动neo4j
下载完成后解压
# 启动
./neo4j start
# 关闭
./neo4j stop
Mac OpenJDK11 JavaFX 环境
OpenJdk 11 or 17 环境下JavaFx开发环境设置
Openfx
-
记录了jdk11和17版本下javafx的使用方式。
-
下载openfx
方式一
pom依赖
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
</dependency>
</dependencies>
Mac 安装 Jenv
简单记录下mac下多版本jdk管理
- https://adoptopenjdk.net/
- https://www.jianshu.com/p/1a147d5515f0
检查环境
查看当前安装的jdk版本
/usr/libexec/java_home -V
# 如果有安装过jdk版本这里会输出信息
SpringBoot Redis 延时队列
之前有介绍过SpringBoot-Delayed-Queue基于jdk实现DelayedQueue。在实际开发中使用redis zset来实现的也比较常见。
- Redis 延迟队列实现的思路,利用 zrangebyscore 查询符合条件的所有待处理任务,循环执行队列任务。或者每次查询最早的一条消息,判断这条信息的执行时间是否小于等于此刻的时间,如果是则执行此任务,否则继续循环检测。
Redis-Sorted-Sets
每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
SpringBoot MDC日志
日常在开发过程中方便排查文件,需要在日志中输出一些关键内容。
MDC
在茫茫日志中定位需要的信息很费时,MDC 全称是 Mapped Diagnostic Context.一个线程安全的存放诊断日志的容器。
演示代码
SpringBoot 定时任务
Scheduling-Tasks
Spring Scheduler里有两个概念:任务(Task)和运行任务的框架(TaskExecutor/TaskScheduler)。TaskExecutor顾名思义,是任务的执行器,允许我们异步执行多个任务。TaskScheduler是任务调度器,来运行未来的定时任务。触发器Trigger可以决定定时任务是否该运行了,最常用的触发器是CronTrigger,具体用法会在下面章节中详细介绍。Spring内置了多种类型的TaskExecutor和TaskScheduler,方便用户根据不同业务场景选择。
CentOS7 Nginx GoAccess
GoAccess
GoAccess是一个基于终端的快速日志分析器。其核心思想是实时快速分析和查看Web服务器统计信息,而无需使用您的浏览器(如果您希望通过SSH快速分析访问日志,或者只是喜欢在终端中工作),终端输出是默认输出,但它能够生成完整的,独立的实时 HTML报告(非常适合分析,监控和数据可视化),以及a JSON和CSV报告。
- 数据持久性强,GoAccess能够通过磁盘上的B + Tree数据库逐步处理日志。
- GoAccess是用C语言编写的,要运行它,你只需要将ncurses作为依赖项,它甚至还具有自己的RFC6455兼容Web Socket服务器。
- 跟踪提供请求所需的时间。如果您想跟踪减慢网站速度的网页,则非常有用。
- GoAccess允许任何自定义日志格式字符串。预定义选项包括Apache,Nginx,Amazon S3,Elastic Load Balancing,CloudFront等。
- 所有面板和指标都定时在终端输出上每200毫秒更新一次,在HTML输出上每秒更新一次。
SpringBoot Lucene
Lucene
在Java领域常用的搜索框架鼻祖Lucene,现在常用的Solr和ElasticSearch底层都是基于Lucene
企业架构分布式锁
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。是为了解决分布式系统中,不同的系统或是同一个系统的不同主机共享同一个资源的问题,它通常会采用互斥来保证程序的一致性。
锁
锁是一种常用的并发控制机制,用于保证一项资源在任何时候只能被一个线程使用,如果其他线程也要使用同样的资源,必须排队等待上一个线程使用完。

SpringBoot 动态数据源
在对老系统进行saas改造的时候,在项目初期使用了动态数据源的方式处理业务。
- 本文内容仅针对数据存储方案。
动态数据源
**SaaS是Software-as-a-service(软件即服务)**它是一种通过Internet提供软件的模式,厂商将应用软件统一部署在自己的服务器
①独立性:每个租户的系统相互独立。
②平台性:所有租户归平台统一管理。
③隔离性:每个租户的数据相互隔离。
Docker Compose SpringBoot MySQL Redis
在Java的技术栈中可以使用maven插件来构建docker镜像,用起来没有docker-compose好用。
实现目标
- spring boot 、mysql 、redis 定义正常运行。
- 解决docker compose 启动顺序问题。
- 解决配置文件读取其它容器ip问题。
源码地址
SpringBoot 阻塞队列
之前在订单场景使用过DelayedQueue延时列队,实际上还有阻塞列队的用法。刚工作那会写爬虫的时候有使用过。这里总结下使用。
BlockingQueue
- 阻塞列队,BlockingQueue是java.util.concurrent包下的实现类。提供了线程安全的列队访问方式,当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。

Docker Compose Redis 哨兵
上次编写了Docker-Compose-Redis-Master-Slave的文档,完成了简单的主从配置。这次在上次的基础上增加哨兵监控。
编写docker-compose配置文件
- 这里和上次的使用同一个网桥
- Docker-compose 文件和 sentinel配置文件放在同一个目录下。
Docker Compose Redis 主从
Java 雪花算法
Snowflake,雪花算法是由Twitter开源的分布式ID生成算法,以划分命名空间的方式将 64-bit位分割成多个部分,每个部分代表不同的含义。这种就是将64位划分为不同的段,每段代表不同的涵义,基本就是时间戳、机器ID和序列数,当然这种方案就是需要考虑时钟回拨的问题以及做一些 buffer的缓冲设计提高性能。
背景
Twitter 早期用 MySQL 存储数据,随着用户的增长,单一的 MySQL 实例没法承受海量的数据,开发团队就开始用 Cassandra 和 sharded MySQL 替代原有的系统。然而和 MySQL 不同的是,Cassandra 没有内置为每一条数据生成唯一 ID 的功能,因为在一个分布式环境下,很难有完美的 ID 生成方案。
Redis Geo
源码地址
Geo
Redis 在 3.2 版本中增加了 GEO 类型用于存储和查询地理位置。
-
GEOADD:添加地理位置
-
GEOPOS:查询位置信息
-
GEODIST:距离统计
-
GEORADIUS:以给定的经纬度为中心, 找出某一半径内的元素
-
GEORADIUSBYMEMBER 找出位于指定范围内的元素,中心点是由给定的位置元素决定
-
GEOHASH:返回一个或多个位置元素HASH
-
关于删除,使用集合函数中的zrem,geo本质存在一个集合中。
网络通信 Tcpdump
Tcpdump
dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。
安装
linux
yum install tcpdump
[root@~]# tcpdump --v
tcpdump version 4.9.2
libpcap version 1.5.3
OpenSSL 1.0.2k-fips 26 Jan 2017
Spring SPI
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。
-
本文对比JDK、Spring对SPI机制的实现。
-
在实际的应用场景。
- jdbc驱动,不同的数据有不同的驱动。

com.mysql.cj.jdbc.Driver- spring 也使用spi机制,用于扩展实现。

org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory- dubbo也通过spi机制实现自定义扩展。
- 日志门面接口实现类加载,SLF4J加载不同提供商的日志是现类。
Java Zookeeper
Zookeeper概述
Zookeeper可以让企业的IT架构逐步从集中式向分布式过度,所谓的分布式是指:把一个计算任务分解成若干个计算单元,并且分派到若干不同的计算机中去执行,然后汇总计算结果的过程。
-
Zookeeper介绍
- Zookeeper是源代码开放的分布式协调服务,由雅虎创建,是Google Chubby开源实现。Zookeeper是一个高性能的分布式数据一致性解决方案,它将那些复杂、容易出错的分布式一致性服务封装起来,构成一个搞笑可靠的原语集,并提供一系列简单易用的接口给用户使用。
-
Zookeeper的典型应用场景
- 数据发布/订阅 顾名思义就是一方把数据发布出来,另一方通过某种手动可以得到这些数据。
- 通常数据订阅有两种方式:推模式和拉模式,推模式一般是服务器主动向客户端推送消息,拉模式是客户端主动去服务端获取数据(通常采用的是轮询的方式)。
- Zookeeper采用两种方式的结合。
- 发布者将数据发布到Zookeeper集群节点上,订阅者通过一定的方法告诉服务器,我对那个节点的数据感兴趣,那个服务器在这些节点的数据发送变化时,就通知客户端,客户端得到通知后可以去服务器获取数据信息。
- 分布式协调/通知
- 心跳检测:在分布式系统中,通常需要机器是否可以用,Zookeeper中我们让所有的机器都注册一个临时节点,所以只需要判断这个节点是否存在就可以了,不需要直接去连接需要检查的机器,降低系统的负载度(节点分为临时和持久)。
- 数据发布/订阅 顾名思义就是一方把数据发布出来,另一方通过某种手动可以得到这些数据。
-
Zookpeeper重量级使用
- Hadoop、HBase、Storm、Solr。
-
集群角色
- Leader、Follower、Observer
- Leader服务器是整个Zookeeper集群工作机制的核心
- Follower服务器是Zookeeper集群状态的跟随者
- Oserver服务器充当一个观察者的角色
- Leader、Follower设计模式,Observer观察者模式
- Leader、Follower、Observer
-
会话
- 会话是指客户端Zookeeper服务器的连接,Zookeeper中的会话叫Session,客户端与服务器建立TCP的长连接来维持一个Session,客户端在启动的时候首先会与服务器建立一个TCP连接,通过这个连接客户端能够通过心跳检测与服务器保持有效的会话,也能向Zookeeper服务器发送请求并获得响应。
-
数据节点
- Zookeeper中的节点有两类
- 集群中的一台机器称为一个节点
- 数据模型中的数据单元Znode,分别为持久节点和临时节点。(其实数据节点就是一个tree节点就是Znode)
- Zookeeper中的节点有两类
-
版本
- Zookeeper中的版本
- version
- 当前数据节点数据内容版本
- cversion
- 当前数据节点子节点的版本号
- aversion
- 当前数据节点ACL变更版本号
- version
- Zookeeper中的版本
-
watcher(事件监听器)
- Zookeeper允许用户在指定节点上注册一些Watcher,当数据节点发生变化的时候,Zookeeper服务器会把这个变化通知发送给感兴趣的客户端。
-
ACL权限控制
- ACL是Access Contril Lists 的缩写,Zookeeper采用ACL策略来进行权限控制,有以下权限:
- CREATE:创建子节点
- READ:获取子节点
- WRITE:更新子节点数据权限
- DELETE:删除子节点权限
- ADMIN:设置节点ACL权限
- ACL是Access Contril Lists 的缩写,Zookeeper采用ACL策略来进行权限控制,有以下权限:
SpringBoot JMH
尝试在spring test中使用基准测试。
演示代码
-
JMH 是一个用于在 JVM 上编写基准测试的 Java 工具库,它是作为 OpenJDK 项目的一部分开发的。
-
在与spring test集成过程中,只需要成功加载spring即可。
Console
- 当jmh先启动,在启动spring就正常使用了。
# JMH version: 1.21
# VM version: JDK 1.8.0_275, OpenJDK 64-Bit Server VM, 25.275-b01
# VM invoker: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java
# VM options: -server
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: cn.z201.jmh.AppApplicationTest.environment
# Run progress: 0.00% complete, ETA 00:00:20
# Fork: N/A, test runs in the host VM
# *** WARNING: Non-forked runs may silently omit JVM options, mess up profilers, disable compiler hints, etc. ***
# *** WARNING: Use non-forked runs only for debugging purposes, not for actual performance runs. ***
# Warmup Iteration 1:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [StartupInfoLogger.java : 55] Starting application using Java 1.8.0_275 on z201MacBook-Pro.local with PID 23242 (started by zengqingfeng in /Users/zengqingfeng/word/code-example/SpringBoot-JMH)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [SpringApplication.java : 679] The following profiles are active: dev
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Bootstrap.java : 68] UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ServletContextImpl.java : 371] Initializing Spring embedded WebApplicationContext
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ServletWebServerApplicationContext.java : 289] Root WebApplicationContext: initialization completed in 809 ms
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ExecutorConfigurationSupport.java : 181] Initializing ExecutorService 'applicationTaskExecutor'
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Undertow.java : 120] starting server: Undertow - 2.2.7.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Xnio.java : 95] XNIO version 3.8.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [NioXnio.java : 59] XNIO NIO Implementation Version 3.8.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Version.java : 52] JBoss Threads version 3.1.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [UndertowWebServer.java : 133] Undertow started on port(s) 9031 (http)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [StartupInfoLogger.java : 61] Started application in 2.018 seconds (JVM running for 3.629)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [AppApplicationTest.java : 40] dev
网络通信 Wireshark
Docker Compose Redis MySQL
记录下使用docker-compose构建管理Redis、mysql。
准备工作
- 创建工作目录
$ mkdir -p docker docker/mysql docker/mysql/data docker/redis docker/redis/data
# 使用 tree docker 查看目录结构 yum -y install tree 安装
$ tree docker
docker
├── mysql
│ └── data
└── redis
└── data
$ touch docker/mysql/my.cnf docker/redis/redis.conf
$ tree docker
docker
├── mysql
│ ├── data
│ └── my.cnf
└── redis
├── data
└── redis.conf
CentOS7 Selenium运行环境
最近在编写爬虫程序,这里简单的做下笔记。
阅读注意事项
- 需要一台服务器(阿里ESC)这种,分配的公网ip。
- 这里使用的yum安装,所以环境配置都创建好了,不需要在手动修改。
准备工作
安装Java、maven、git、selenium运行环境
# 使用的机器是centos7.4
# 系统环境一个一个来安装。
# 1.检查是否安装jdk
-> yum install java-1.8.0-openjdk-devel.x86_64
-> java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
-> yum install maven
-> mvn -version
Java version: 1.8.0_262, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-0.el7_8.x86_64/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-862.el7.x86_64", arch: "amd64", family: "unix"
-> yum install git
git version 1.8.3.1
# 查看是否生成过证书
-> ls -al ~/.ssh
# 这里配置下ssh公钥方便git拉去代码
-> ssh-keygen -t rsa -C “you email@gamil.com”
# 查看证书
-> cat ~/.ssh/id_rsa.pub
# 开始配置 selenium 运行环境
-> wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
-> yum localinstall google-chrome-stable_current_x86_64.rpm
# 检查版本
-> google-chrome --version
Google Chrome 85.0.4183.83
# 安装 chromedriver
-> yum install chromedriver
-> chromedriver -version
ChromeDriver 84.0.4147.89
# 这里注意 chromedriver 可能与chrome的版本不一致,去官方网站下载后解压复制到/usr/bin中
# 下载地址 https://chromedriver.chromium.org/
CentOS7 Nginx HTTPS
最近在搭建测试环境,很久没接触nginx了。
阅读注意事项
- 需要一个域名,并且在国内备案过。
- 需要一台服务器(阿里ESC)这种,分配的公网ip。
- 申请或者购买一张证书。和域名做关联,域名解析到服务器的公网ip。注意开放服务区的80、443端口。
- 证书有两个文件
domian.name.key domain.name.pem
- 吧证书上传到目标nginx服务器中。
- 检查服务器防火墙
- 证书有两个文件
Java JMH
SpringBoot 修改Tomcat版本
本章只是回顾一次eureka版本升级后tomcat资源占用过高的问题,临时解决。
升级springBoot、SpringCloud版本
- 升级完成后直接在测试环境测试部署,结果发现eureka的cpu资源占用过高,导致假死。通过arthas发现是tomcat线程阻塞。通过dependepency看了下springboot中内嵌tomcat的版本是9了。之前是8,测试环境一大堆人等着测试接口。首先想着降低tomcat版本。
查看依赖
gradle dependencies
mvn dependency:tree > output.txt # 输出到文件里
Java Eureka 钉钉通知
本篇幅只是回顾使用eureka的时候如何钉钉告警。
Eureka钉钉告警
- 实例图

关键代码
@EventListener
public void listen(EurekaInstanceCanceledEvent event) {
log.error("告警通知 [{}] 服务注销 timestamp [{}] serverId [{}]",
event.getAppName(),
event.getTimestamp(),
event.getServerId());
if (!event.isReplication()) {
ServiceNotice serviceNotice = new ServiceNotice();
serviceNotice.setTitle("告警通知 服务下线");
serviceNotice.setAppName(event.getAppName());
serviceNotice.setTimestamp(event.getTimestamp());
serviceNotice.setServerId(event.getServerId());
serviceNotice.setProfiles(active);
alarmNoticeManage.createNotice(serviceNotice, "");
}
}
@EventListener
public void listen(EurekaInstanceRegisteredEvent event) {
log.info("告警通知 [{}] 服务注册 timestamp [{}] id [{}] ipAddr [{}] ",
event.getInstanceInfo().getAppName(),
event.getTimestamp(),
event.getInstanceInfo().getId(),
event.getInstanceInfo().getIPAddr()
);
if (!event.isReplication()) {
ServiceNotice serviceNotice = new ServiceNotice();
serviceNotice.setTitle("告警通知 服务上线");
serviceNotice.setAppName(event.getInstanceInfo().getAppName());
serviceNotice.setTimestamp(event.getTimestamp());
serviceNotice.setServerId(event.getInstanceInfo().getId());
serviceNotice.setProfiles(active);
alarmNoticeManage.createNotice(serviceNotice, "");
}
}
SpringBoot 错误钉钉通知
本篇幅只是回顾使用钉钉做异常告警需要那些关键业务信息。
为什么要做钉钉通知?
事情要从我入职上家公司说起,进入公司后把线上项目clone下来大致看了下。代码风格过于滞后、编码风格混乱。进入公司第一周就出现了线上故障,嗯。我去线上检查日志,emmmm竟然没有日志输出。这次故障是由客户反馈来的。当时我非常吃惊,大伙好像很淡定的样子,习以为常了?
想到当初面试的时候和总监的谈话,主要是带领团队落地微服务架构,看来必须大刀阔斧了。
首先想到的时候改进日志输出、定义全局异常级别,根据异常级别输出日志。
Java JVM
本章是整理知识内容,为强化知识长期更新。
JVM
JVM 全称 Java Virtual Machine,也就是我们耳熟能详的 Java 虚拟机。JVM 会翻译执行 Java 字节码,然后调用真正的操作系统函数,这些操作系统函数是与平台息息相关的。

- 如上图所示,通过JVM,Java实现了跨平台、只要class文件能正常执行,就可以在其他系统上面运行。 JVM 与操作系统之间的关系:JVM 上承开发语言,下接操作系统,它的中间接口就是字节码。
CentOS7 OpenResty 部署
OpenResty
OpenResty(又称:ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台,由中国人章亦春发起,提供了很多高质量的第三方模块。OpenResty 是一个强大的 Web 应用服务器
安装方法
- 通过源安装
- 编译安装
源安装
- 安装yum-utils
yum install yum-utils
Redis CLI
在mac中使用redis-cli。相比rdm我可能更喜欢这个命令行工具。
在mac中之安装redis-cli
按照标准的按照流程,需要先安装redis-server。
brew tap ringohub/redis-cli
brew update && brew doctor
brew install redis-cli
CentOS7 Nginx 日志
公司没有日志采集平台,又不太可能在业务系统里面搞事情。好在之前有玩过elk日志分析组合。直接从服务器上面撸出日志简单的用linux命令分析下吧。
Ngxin 日志格式化
- Nginx提供的访问日志里就蕴藏着大量有用信息。今天这篇要说的就是如果修改Nginx默认日志格式,以便于我们更好的挖掘有效指标。
编辑/etc/nginx.conf配置文件,在日志部分添加下面两段代码,编辑完成后重启Nginx服务即可。
编程式代码风格
好久没更新博客,最近公司让我出一个代码规范,我吓了一跳。赶忙翻出阿里《 码出高效》,不敢造次,我就补充点个人的想法吧。代码是给人看的。代码风格应该遵循
极简主义

写好代码
- 可维护性(maintainability)
- 所谓的“维护”无外乎就是修改 bug、修改老的代码、添加新的代码之类的工作。所谓“代码易维护”就是指,在不破坏原有代码设计、不引入新的 bug 的情况下,能够快速地修改或者添加代码。
- 可读性(readability)
- 我们在编写代码的时候,时刻要考虑到代码是否易读、易理解。除此之外,代码的可读性在非常大程度上会影响代码的可维护性。
- 可扩展性(extensibility)
- 我们在不修改或少量修改原有代码的情况下,通过扩展的方式添加新的功能代码。说直白点就是,代码预留了一些功能扩展点,你可以把新功能代码,直接插到扩展点上,而不需要因为要添加一个功能而大动干戈,改动大量的原始代码。
- 灵活性(flexibility)
- 灵活性是一个挺抽象的评价标准。如果一段代码易扩展、易复用或者易用,我们都可以称这段代码写得比较灵活。
- 简洁性(simplicity)
- KISS 原则:“Keep It Simple,Stupid”。这个原则说的意思就是,尽量保持代码简单。代码简单、逻辑清晰,也就意味着易读、易维护。我们在编写代码的时候,往往也会把简单、清晰放到首位。
- 可复用性(reusability)
- 代码的可复用性可以简单地理解为,尽量减少重复代码的编写,复用已有的代码。在后面的很多章节中,我们都会经常提到“可复用性”这一代码评价标准。
- 可测试性(testability)
- 代码的可测试性差,比较难写单元测试,那基本上就能说明代码设计得有问题。
SpringBoot Redis 超时错误
最近在看项目的时候发现一个临时问题,就是redis.timeout设置0依然超时的问题。
- 代码适用版本
jedis:2.9.0,org.springframework.data.redis:1.8.1
timeout设置0的问题
spring.redis.timeout =0 如果设置成0 redis默认超时时间就是2秒.

Java Arthas
基础理论篇学习笔记
Arthas(阿尔萨斯) 能为你做什么?

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
Docker Compose Redis 缓存击穿
关于Redis场景下简单的处理方式。
缓存穿透和缓存击穿
- 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。
- 解决办法
- 缓存空对象:代码维护较简单,但是效果不好。不过部分场景能使用。
Docker ElasticSearch5.6.8 部署
docker查找镜像
docker search elasticSearch

docker 拉去镜像
docker pull elasticsearch:5.6.8 直接拉去官方的镜像, 可以使用指定版本。

Spring Redis 字符串
本章是整理知识内容,为强化知识长期更新。
spring-redis-string
Spring-data-redis 有两个客户端,本章节主要使用lettuce来作为代码演示。尽可能面向redis编程。
- 参考文献redis-string
Docker Mysql5.7 部署
docker查找镜像
docker search mysql

docker 拉去镜像
docker pull mysql:5.7 直接拉去官方的镜像, 可以使用指定版本。

Docker Zookeeper 部署
本章是整理知识内容,为强化知识长期更新。
docker查找镜像
docker search zookeeper

docker 拉去镜像
docker pull zookeeper 直接拉去官方的镜像,一般第一个就是。
Docker Redis 部署
本章是整理知识内容,为强化知识长期更新。
Docker环境下部署redis
确认已经安装好了Docker环境
windows 和 linux 可以用 docker info检查是否安装
- 在mac下就是这么个情况。需要注意的是,请不用使用email登录,否则在查找官方镜像的时候会抛出认证失败的问题。比如我是登录用户
z201
docker查找镜像
SpringBoot Dubbo
离职两个月,太久没写项目了,重新温故下。
-
这里的代码是最简单的演示效果。
-
项目下载地址
git cloen -b v1.0.0 https://github.com/z201/learning-spring-dubbo-micro-service.git -
v1.0.0分支dubbo xml 配置演示基于zk做注册中心。 -
v2.0.0分支dubbo annotation 配置演示基于zk做注册中心。 -
v3.0.0分支dubbo xml 配置演示基于nacos做注册中心。
Java Code 递归
上周的一道笔试题
递归计算
根据两组参数,使用递归完成编程。
递归方法
参数1 [1,3]
参数2 n
当参数2 < 小于参数1中元素个数的时候,不输出。
当n = 3 时 输出 [1,3,4]
当n = 4 时 输出 [1,3,4,7]
当 n = 11 使用递归程序输出
public static void test(List<Integer> list , Integer end) {
if(list.isEmpty() || list.size() < 1 || end == null || end < 0){
throw new RuntimeException("初始化参数异常");
}
if (list.size() < end) {
int length = list.size();
list.add(list.get(length - 1) + list.get(length - 2));
test(list , end);
}
}
public static void main(String[] args) {
Integer[] arr = new Integer[]{1,3};
List<Integer> list = new ArrayList(Arrays.asList(arr));
test(list , 11);
System.out.println(list.toString());
}
>>
[1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199]
CentOS7 ELK 部署
18年年初的笔记,被我翻出来了。
EL(B)K平台
Elastic Stack(旧称ELK Stack),是一种能够从任意数据源抽取数据,并实时对数据进行搜索、分析和可视化展现的数据分析框架。(hadoop同一个开发人员)
EL(B)K是啥技术
CentOS7 Sonarqube 部署
Java Selenium
Selenium
Selenium是最广泛使用的开源Web UI(用户界面)自动化测试套件之一。它最初由Jason Huggins于2004年开发,作为Thought Works的内部工具。Selenium支持跨不同浏览器,平台和编程语言的自动化。
-
Selenium可以轻松部署在Windows,Linux,Solaris和Macintosh等平台上。此外,它支持iOS(iOS,Windows Mobile和Android)等移动应用程序的OS(操作系统)。
-
Selenium通过使用特定于每种语言的驱动程序支持各种编程语言.Selenium支持的语言包括C#,Java,Perl,PHP,Python和Ruby。目前,Selenium Web驱动程序最受Java和C#欢迎。Selenium测试脚本可以使用任何支持的编程语言进行编码,并且可以直接在大多数现代Web浏览器中运行。Selenium支持的浏览器包括Internet Explorer,Mozilla Firefox,Google Chrome和Safari。
Java JJWT JUnit4
Jjwt-Junit
本章内容主要是用来实际运行下jjwt的api,完成相应的单元测试。
<properties>
<junit.version>4.12</junit.version>
<jjwt.version>0.10.5</jjwt.version>
<lmbok.version>1.18.4</lmbok.version>
<h2.version>1.4.197</h2.version>
<slf4j.version>1.7.25</slf4j.version>
<logback.version>1.2.3</logback.version>
<!-- pom文件需要指定打包编码集,[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent! -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<!--log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 测试框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
Java JUnit4
本文主要是为了记录很久以前对Junit的回顾。
Junit
Java开发中使用的最多的测试框架,工作中经常会大量使用。
建议遵守约定
- 测试类在test包下(如果是maven结构的项目建议建议不要方在源码中,早期的项目很多是没有区分开的)
- 测试类命名xxxTest结尾。
- 方法命名testxxxx命名。
- 测试方法上必须使用@Test进行修饰。
- 测试方法必须使用public void 进行修饰,不能带任何的参数。
- 测试类的包应该和被测试类保持一致。
- 测试单元中的每个方法必须独立测试,测试方法间不能有任何的依赖。
Java Web JSON Token
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。也就是说JWT是Token的一种表述性声明规范。
JWT(Json Web Token)
- 官网地址:https://jwt.io/
- jwt github:https://github.com/jwtk/jjwt
编程式 FastDFS
FastDfs介绍
-
FastDFS是由国人余庆所开发,其项目地址:FastDFS。FastDfs是一个轻量级的开源分布式文件系统,主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。文件存取时实现了负载均衡FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储支持存储服务器在线扩容支持相同内容的文件只保存一份,节约磁盘空间。
-
FastDFS只能通过Client API访问,不支持POSIX访问方式。
-
FastDFS特别适合大中型网站使用,用来存储资源文件(如:图片、文档、音频、视频等等)。
-
它用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。它只能通过专有API对文件进行存取访问,不支持POSIX接口方式,不能mount使用。准确地讲,Google FS、HDFS、TFS(这三个都是底层上的实现,在文件系统上处理的是数据块)以及FastDFS、mogileFS(这两个是文件级上的实现,处理的是文件)等类Google FS都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。
-
特性
-
1、分组存储,灵活简洁、对等结构,不存在单点。 2、文件ID由FastDFS生成,作为文件访问凭证。FastDFS不需要传统的name server(去重机制在服务端,导致不能达到秒传。)。 3、和流行的web server无缝衔接,FastDFS已提供apache和nginx扩展模块。 4、大、中、小文件均可以很好支持,支持海量小文件存储(实际上不建议存储超大文件(大于500M))。 5、支持多块磁盘,支持单盘数据恢复(理论上,实际出现Storage合并丢操作失数据)。 6、支持相同文件内容只保存一份,节省存储空间。 7、存储服务器上可以保存文件附加属性。 8、下载文件支持多线程方式,支持断点续传。
-
Java XPath
了解Xpath之前先了解下XML、HTML。如果完全不知道是什么,建议系统学习HTML、XML下阅读下文。
XML
可扩展标记语言(英语:Extensible Markup Language,简称:XML),是一种标记语言。标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用像XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从标准通用标记语言(SGML)中简化修改出来的。它主要用到的有可扩展标记语言、可扩展样式语言(XSL)、XBRL和XPath等。
Java MyBatis JUnit4
mybatis小试牛刀 在此基础上添加log日志。
-
官方文档 : http://www.mybatis.org/mybatis-3/zh/logging.html
-
项目地址 : mybatis-learning-02
Java MyBatis H2 JUnit4
Java Spring
本章是整理知识内容,为强化知识长期更新。

Spring
- Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。
Spring IOC = Spring Bean + Spring Context特性
Java Maven
本章是整理知识内容,为强化知识长期更新。
Mavan常用命令以及用法
-
常用命令就要先了解Maven的生命周期
- Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
- Maven的生命周期是抽象的,即生命周期不做任何实际的工作,实际任务由插件完成,类似于设计模式中的模板方法。所以必须有对应的插件才能执行对于的步骤。
- Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
- clean生命周期:清理项目,包含三个phase。
- 1.)pre-clean:执行清理前需要完成的工作。
- 2)clean:清理上一次构建生成的文件。
- 3)post-clean:执行清理后需要完成的工作。
- default生命周期:构建项目,重要的phase如下。
- 1)validate:验证工程是否正确,所有需要的资源是否可用。
- 2)compile:编译项目的源代码。
- 3)test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
- 4)Package:把已编译的代码打包成可发布的格式,比如jar。
- 5)integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
- 6)verify:运行所有检查,验证包是否有效且达到质量标准。
- 7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
- 8)Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
- site生命周期:建立和发布项目站点,phase如下。
- 1)pre-site:生成项目站点之前需要完成的工作。
- 2)site:生成项目站点文档。
- 3)post-site:生成项目站点之后需要完成的工作。
- 4)site-deploy:将项目站点发布到服务器
- clean生命周期:清理项目,包含三个phase。
-
mvn clean
- 清理项目构建文件。调用clean生命周期的clean阶段,实际执行pre-clean和clean阶段。
-
mvn install
- 构建项目文件。实际执行pre-clean和clean,install以及之前所有阶段。
-
mvn install -Dmaven.test.skip=true
-
构建项目的时候不执行测试。也可以使用插件来配置。
<!-- surefire 插件用来在maven构建生命周期的test phase执行一个应用的单元测试 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <skipTests>true</skipTests> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> </configuration> <!-- 插件手动匹配JUnit 目前是使用4.10的版本--> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>2.19.1</version> </dependency> </dependencies> </plugin>
-
-
mvn eclipse:eclipse
- 将pom项目转换成eclipse格式项目。
-
mvn jetty:run -war
-
使用内置jetty启动项目,需要配置jetty扩展插件。也可以使用tomcat来作为插件。
<!-- 配置Maven插件(mvn jetty:run -war可以运行项目) --> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.3.0.M1</version> <configuration> <!-- 指定访问端口 --> <httpConnector> <port>80</port> </httpConnector> <!-- 间隔x扫描一次,实现热部署 <scanIntervalSeconds>0</scanIntervalSeconds> --> <!-- 编写类文件之后,是否自动重启jetty;可选后面两个值[manual|automatic] <reload>manual</reload> --> <!-- 指定关闭端口 --> <stopPort>9998</stopPort> <stopKey>stop-jetty</stopKey> <webApp> <!-- 配置<contextPath>/</contextPath>,则访问路径为http://localhost:80 --> <contextPath>/</contextPath> <!-- 更改jetty默认webdefault.xml文件,主要修改了useFileMappedBuffer属性为false,使其不锁定静态文件 --> <!-- 此文件在C盘\用户目录\.m2\repository\org\eclipse\jetty\jetty-webapp\9.1.0.RC1\找到jar包,打开jar包目录org\eclipse\jetty\webapp\目录中 --> <!-- <defaultsDescriptor>webdefault.xml</defaultsDescriptor> --> <defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor> </webApp> </configuration> </plugin>
-
Java Code 交换值
刚去杭州面试的第二家公司,做笔试的时候的时候遇到的。最近几天在整理以前的笔记发现了。简单记录下。
互换两个变量的值
int a=10; int b=12; // 通过两个变量之间的运算输出结果 a = 12 b = 10
Spring Upgrade SpringBoot
2018年在公司负责了一段时间老项目改造升级工作。因此记录下折腾的过程。
- Spring boot 最近挺火的,之前的工作并没有机会去实战。但是即使不使用Spring boot 也是可以做零配置的。
约定大于配置
- servlet3.*的规范已经支持不使用web.xml了。
- annotation的配置方式在Spring其实也存在很久了。
直奔主题
代码配置web.xml
org.springframework.web.WebApplicationInitializer
Mac 编程环境
最近开始用mac来开发。记录下环境安装过程方便以后快速恢复熟悉的开发环境。
这里提前修改一下控制台前缀
[dev mc]$ sudo vim /etc/bashrc
#修改以下内容
PS1='\h:\W \u\$ '
#修改成
PS1='[dev \u]$ '
Java Log4j
本章内容阐述个人理解,以及使用方法。若有不正确的内容欢迎斧正。睡觉之前赶快记录下来免得有忘记了。
什么是Log?
- 日志记录的是什么?市面上流行的软件基本都有日志记录功能,作为开发人员的好帮手。日志可以有效的记录程序运行的状态以及运行的异常,比如说操作系统蓝屏了、手机死机了、软件卡死、程序崩溃、写了BUG等等都会有对应的日志留下。
如何利用log?
- 笔者是一个Java开发人员,本章内容代码部分已Java代码用例。大家都知道日志非常重要,但是经验不足的开发人员往往忽视了这个重要的手段,比如在控制台输出日志,所有输出信息都集中在一起。排除问题非常困难,一旦出现了线上异常信息首先要看的就是日志信息。所以有必要就日志手段多了解下。
网络通信 Modbus
本章是整理知识内容,为强化知识长期更新。
以下部分超链接需要科学上网。
ModBus
modbus是一种通讯协议,是Modicon公司1979年为使用可编程逻辑控制器(PLC)通讯而发表。Modbus是工业领域通讯协议的业界标准之一,目前也我国国家标准工业通讯协议中的重要成员之一。
介绍
-
Modbus采用主从(Master-Salve)通信模式,仅有主设备(Master)能对传输进行初始化,从设备(Slave)根据主设备的请求进行应答。 在主从关系中,通信总是成对发生。一个设备必须发起请求,然后等待响应 - 并且发起设备(主设备)负责发起每次交互。 通常,主设备是人机界面(HMI)或监控和数据采集(SCADA)系统,从设备是传感器、可编程逻辑控制器(PLC)或可编程自动化控制器(PAC)。 这些请求和响应的内容以及发送这些消息的网络层由协议的不同层来定义。
- 在串行链路的主从通信中,Modbus主设备可以连接一个或N(最大为247)个从设备,主从设备之间的通信包括单播模式和广播模式。
- 在广播模式中,Modbus主设备可同时向多个从设备发送请求(设备地址0用于广播模式),从设备对广播请求不进行响应。
- 在单播模式中,主设备发送请求至某个特定的从设备(每个Modbus从设备具有唯一地址),请求的消息帧中会包含功能代码和数据,比如功能代码“01”用来读取离散量线圈的状态。从设备接到请求后,进行应答并把消息反馈主设备。
- __主设备不发送数据,从数据是不会自己发出数据的;即必须是主设备发出查询请求才能建立通讯。 __
-
消息帧校验方式
- ASCII消息帧:
LRC(纵向冗长检测) - CRCi消息帧:
CRC(循环冗长检测)
- ASCII消息帧:
-
ModBus是OSI模型第七层上即__应用层__报文传输协议。
-
ModBus支持多工业设备、包括
PLC、DSC、变频器、智能仪表等都在应用。 -
ModBus支持多种电气接口,如
RS-232、RS-485等,还可以在各种介质上传送,如双绞线、光纤、无线。 -
ModBus协议完全免费;
帧格式简单,紧凑。 -
ModBus对线缆的要求、长度、波特率,终端电阻,接地,连接器,通信状态的LED指示,都有电气标准。
-
ModBus数据可以分为两大类,分别为Coil和Register,每一种数据,根据读写方式的不同,又可细分为两种(只读,读写)。
- Coli是位(bit)变量。
- Register是整型(word ,即 16 - bit )。
CentOS7 Redis 部署
Redis全称:Remote Dictionary Server(远程数据服务)。Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
单实例安装
只是学习使用使用yum 方式安装比较快。而且centos自带官方源。
yum安装
- yum install epel-release --下载fedora的epel仓库
- yum install redis -- 安装redis数据库
CentOS7 RabbitMQ 部署
RabbitMQ介绍
RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。 AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。
CentOS7 MongoDB 部署
mongodb的安装方式比较简单,下面演示在CentOS7上用yum方式安装。
参考文献
- 下载地址 https://www.mongodb.com/download-center#community
- 在线文档 https://docs.mongodb.com/manual/introduction/
使用yum方式安装
仅供学习参考,若在生产环境中部署请注意修改安全配置。
CentOS7 基础命令
linux作为个人工作经常使用的系统、做下简单的记录方便以后工作参考。
ps
ps命令用于报告系统某个时间内进程的情况
- 参数
-A : 所有的进程均显示出来
-a : 不与terminal有关的所有进程
-u : 有效用户的相关进程
-x : 一般与a参数一起使用,可以列出比较完整的信息。
-l : 较详细地将PID的信息列出。
Java Eureka Zookeeper
服务注册中心,给客户端提供可供调用的服务列表,客户端在进行远程服务调用时,根据服务列表然后选择服务提供方的服务地址进行服务调用。服务注册中心在分布式系统中大量应用,是分布式系统中不可或缺的组件,例如rocketmq的name server,hdfs中的namenode,dubbo中的zk注册中心,spring cloud中的服务注册中心eureka。 在spring cloud中,除了可以使用eureka作为注册中心外,还可以通过配置的方式使用zookeeper作为注册中心。既然这样,我们该如何选择注册中心的实现呢?
CAP定理
CentOS7 MySQL 部署
Centos7的yum源中默认是没有mysql,因为现在已经用mariaDB代替mysql了。
安装前检查
检查linux系统版本
[root@localhost backup]# cat /etc/system-release
CentOS Linux release 7.4.1708 (Core)
CentOS7 Java环境配置
- 本章内容为早期笔记迁移。
- 阅读提醒,权限root.操作流程并位遵循安全规则;线上环境请勿模仿。
文件存放位置。
- opt
- backup
- javahome
- mavenhome
- gradlehome
mkdir -p /opt/{backup,javahome,mavenhome,gradlehome}