Spring AOP无侵入实现日志

平常我们聊起Spring Aop的使用场景最多的就是权限拦截,统一日志等。那么什么样的日志是比较优雅的实现方式?我们在开始实现日志前首先思考,什么样的日志是好的日志?需要满足哪些属性?达到什么样的目的? 简介 日志好比叙事,谁在什么时间发生了什么事,事情的结果是什么?满足这4点就能算得上合格的日志。 实现 定义一个日志描述类,描述日志产生的用户(系统)、主体、时间、地点、行为、结果、变化过程、异常等。 @Setter @Getter @Builder @ToString public class Log implements Serializable { /** * 日志唯一id,用于标记日志等唯一性 */ private Serializable id; /** * 日志发生在那个系统 */ […]

Mybatis插件实现数据隔离

在Sass平台中,多个用户之间的数据是相互隔离的;那么是如何实现的尼?通过日常的开发经验中,总结出两个指标来衡量数据之间的联系。 简介 隔离级别与共享程度,两个指标标识中数据之间的联系性,目前数据有三种方案。 方案隔离级别数据共享数据库隔离高低表隔离中中字段隔离低高 本文主要针对第三种,也就事字段隔离进行讨论实现。 准备 准备一个mysql数据库实例,并创建表; CREATE TABLE `t_order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL, `name` varchar(45) DEFAULT NULL, `tenant_id` bigint(20) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 实现 @Component @Intercepts({ @Signature(type […]

Mysql主从复制

MySQL 复制是一个允许数据同时从一台服务器复制到另一台服务器的过程。 主要是为了增加数据的可用性。 选择 MySQL 主从复制的主要原因之一是数据恢复。 在发生任何灾难或硬件故障的情况下,MySQL 复制可确保始终存在准确的备份。 本文主要针对一主一从进行配置,我们利用docker-compose快捷进行生成mysql5.7实例。 配置mysql容器 version: "3.9" services: m1: image: mysql:5.7.38 container_name: m1 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: dev volumes: […]

Let’s Encrypt 即刻让你全站开启https

Let’s Encrypt is a free, automated, and open Certificate Authority. 继 Mozilla 做出对沃通WoSign的处罚决定之后,谷歌也跟随了这一做法,从 Chrome 56 开始,不再信任沃通及被其收购的 StartCom 于 2016 年 10 月 21 日之后所颁发的证书。 Let’s Encrypt成了我们最佳的选择。当然阿里云也能申请免费的证书,其有效期为一年。虽然Let’s Encrypt的证书只有三个月,但是这并不能阻挡我们喜欢它的接口,更何况我们也可以通过其他手段达到无限续命的方式。比如上、上、下、下、左、右、左、右、B、A、B、A,老子又有30条命了。什么鬼? 开始 Let’s Encrypt官方为我们提供了一个非常好用的工具—certbot。我们能够使用简单的几个命令就能成功的安装一个证书。 下载cerbot 我的服务器是CentOS 7.3 64位/1G RAM/1Mbps/1 core 想必大家已经猜到了,没错就是阿里云的新手免费6个月ECS,这真的不是一个广告,相信我。以下指令都会使用root权限,所以你懂的sudo。 wget https://dl.eff.org/certbot-auto chmod a+x ./certbot-auto 安装证书 非常简单安装证书只需要一个命令 ./certbot-auto certonly --email askCheng@163.com -d blog.well-known.me 有两个参数,不用解释了吧!一路确认就OK了。你可能会遇到两个问题。 问题一: Creating virtual environment... Installing Python packages... 你会卡在这里很久,没反应。原因是下载安装python遇到墙了。解决办法; cd ~/.pip vi pip.conf //或者直接 vi ~/.pip/pip.conf 把内容修改成下面这样 [global] index-url=http://mirrors.aliyun.com/pypi/simple/ [install] trusted-host=mirrors.aliyun.com 在刚刚失败的地方接着往下走,接下来它会让你选择一种方式去 […]

HTTPS 为何安全?

HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少 HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL HTTP 与 HTTPS 区别 http明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。 使用https 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,免费且好用的证书,[Let’s Encrypt](Let’s Encrypt - Free SSL/TLS Certificates),但证书的有效期只要3个月。好用指的是它的申请方式和浏览器的支持程度。 http 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。 http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。 https 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP […]

利用minio自建图床

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 安装 我们一般推荐安装到linux服务器中,当然我们这里只介绍单机安装方式,集群方式可以参考官方文档 wget https://dl.min.io/server/minio/release/linux-amd64/minio #下载 chmod +x minio ./minio server /data # /data将是你存储数据的地方 到这里就已经安装部署完成,是不是很简单。接下来进行验证安装 使用浏览器进行验证 MinIO Server带有一个嵌入的Web对象浏览器,安装后使用浏览器访问http://127.0.0.1:9000,如果可以访问,则表示minio已经安装成功。默认账号均为minioadmin 上传文件 在上传之前我们必须做两件事。 1. 创建bucket 点击右下角的加号,选择第二个按钮,Create bucket.创建成功后类似左边导航栏。 2. 设置bucket访问权限 点击bucket右边的三个点 —> 选择Edit policy —> Read Only。 上传 点击右下角加号,选择第一个按钮Upload file 然后选择文件进行上传。等待上传完成。 图片链接 点击分享按钮,就会弹出访问链接。 这个时候你可能会问,这个链接的有效时间只有5天,最长也就7天,我可能需要一个永久的链接。 Pi 推荐一个图床软件Pi。Pi聚合了多个图床服务器,任您使用。该软件也是开源的,你可以到这里进行查看 Pi里面自然支持minio服务器,可以通过Pi获取永久的图片链接。 […]

Spring boot 注解详解

Spring 注解详解 1. SpringBoot/Spring @SpringBootApplication: 包含@Configuration、@EnableAutoConfiguration、@ComponentScan通常用在主类上。 @Repository: 用于标注数据访问组件,即DAO组件。 @Service: 用于标注业务层组件。 @RestController: 用于标注控制层组件(如struts中的action),包含@Controller和@ResponseBody @Controller: 用于标注是控制层组件,需要返回页面时请用@Controller而不是@RestController @Component: 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 @ResponseBody: 表示该方法的返回结果直接写入HTTP response body中。一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径, 加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据 @RequestBody: 参数前加上这个注解之后,认为该参数必填。表示接受json字符串转为对象 List等。 @ComponentScan: 组件扫描。个人理解相当于,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean* @Configuration: 指出该类是 Bean 配置的信息源,相当于XML中的,一般加在主类上。 @Bean: 相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理 @EnableAutoConfiguration: 让 Spring Boot 根据应用所声明的依赖来对 Spring 框架进行自动配置,一般加在主类上 @AutoWired: byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错 @Qualifier: […]

nginx 拦截同一端口的不同资源

不知道写什么 能这么配置的在我看来应该没有,但是留着吧,说不定哪天自己SB了,会用上了呢.这种事儿谁说得准呢! server { listen 75; server_name blog.well-known.me; location /a/b/c/d/ { proxy_pass http://127.0.0.1:9090; […]

Nginx 配置https并反向代理多台服务器

正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。 什么是正向代理 正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。 什么是反向代理 反向代理实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。 直接上配置文件,如果你问我配置文件在哪里…呵呵 /etc/nginx/nginx.conf 不相信,就找一下. server { listen 80; server_name localhost; #重写协议 […]

HTTP2学习与研究

早期版本的 HTTP 协议的设计初衷主要是实现要简单: HTTP/0.9 只用一行协议就启动了万维网;HTTP/1.0 则是对流行的 HTTP/0.9 扩展的一个正式说明;HTTP 1.1 则是 IETF 的一份官方标准;请参阅 HTTP 简史。 因此,HTTP/0.9-1.x 实现了其目的:HTTP 是应用最广泛、采用最多的一个互联网应用协议。 设计和技术目标 早期版本的 HTTP 协议的设计初衷主要是实现要简单: HTTP/0.9 只用一行协议就启动了万维网;HTTP/1.0 则是对流行的 HTTP/0.9 扩展的一个正式说明;HTTP 1.1 则是 IETF 的一份官方标准;请参阅 HTTP 简史。 因此,HTTP/0.9-1.x 实现了其目的:HTTP 是应用最广泛、采用最多的一个互联网应用协议。 然而,实现简单是以牺牲应用性能为代价的: HTTP/1.x 客户端需要使用多个连接才能实现并发和缩短延迟;HTTP/1.x 不会压缩请求和响应标头,从而导致不必要的网络流量;HTTP/1.x 不支持有效的资源优先级,致使底层 TCP 连接的利用率低下;等等。 这些限制并不是致命的,但是随着网络应用的范围、复杂性以及在我们日常生活中的重要性不断增大,它们对网络开发者和用户都造成了巨大负担,而这正是 HTTP/2 要致力于解决的: HTTP/2 通过支持标头字段压缩和在同一连接上 进行多个并发交换,让应用更有效地利用网络资源,减少 感知的延迟时间。具体来说,它可以对同一连接上的请求和响应消息进行交错 发送并为 HTTP […]

冒泡排序

冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。 冒泡排序 冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 冒泡排序算法的运作如下: 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 冒泡排序的分析 交换过程图示(第一次): bubblesort 那么我们需要进行n-1次冒泡过程,每次对应的比较次数如下图所示: compare def bubble_sort(alist): for j in range(len(alist)-1,0,-1): # j表示每次遍历需要比较的次数,是逐渐减小的 for i in range(j): if alist[i] > alist[i+1]: […]

gpg的使用总结

gpg常用命令 生成密钥 gpg --generate-key #或者 gpg --gen-key #ps: 生成gpg密钥,一些参数是默认的 列出私钥 gpg -K 或 --list-secret-keys # 查看私钥,参数后面没有指定私钥,则输出所有私钥; 列出公钥 gpg -k 或 --list-public-keys # 查看公钥,参数后面没有指定公钥,则输出所有公钥; 导出公钥 gpg -a -o public-file.key --export keyId # 导出公钥keyId到文件public-file.key中; # -a 为 --armor 的简写,表示密钥以ASCII的形式输出,默认以二进制的形式输出; # -o 为 --output 的简写,指定写入的文件; 导出私钥 gpg -a -o private-file.key --export-secret-keys keyId # 导出私钥 keyId 到文件 private-file.key中, # 导出的时候需要输入密钥密码; 导入公钥/私钥 gpg --import public-file.key / private-file.key # 导入公钥或私钥,其中,导入私钥需要输入保护私钥的密码; 删除公钥 gpg […]

Homebrew安装历史版本软件

众所周知homebrew安装软件都是最新版本,那么如何安装历史版本尼? 下面我将以Intellij-idea-ce安装为例,其他软件都是同理 获取软件信息 jhon@jhondeMacBook-Pro ~ % brew info --cask intellij-idea-ce intellij-idea-ce: 2020.3,203.5981.155 (auto_updates) https://www.jetbrains.com/idea/ /usr/local/Caskroom/intellij-idea-ce/2020.2.4,202.8194.7 (130B) From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/intellij-idea-ce.rb ==> Names IntelliJ IDEA Community Edition IntelliJ IDEA CE ==> Description IDE for Java development - community edition ==> Artifacts IntelliJ IDEA CE.app (App) ==> Analytics install: 1,924 (30 days), 5,432 (90 days), 21,956 (365 days) 获取历史版本提交记录 访问地址 https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/intellij-idea-ce.rb Url来自上面的输出。 点击history 找到你想要下载的版本,这里以红框中为例。复制提交commit记录(图中2位置) 安装 cd "$(brew --repo homebrew/cask)" git checkout 16a6ea87ceb92e312df2ed73a203146a9ef7d76e brew install […]

git常用命令

gi t常用命令 预览要删除的文件 $ git rm -r -n --cached "bin/" //此命令是展示要删除的文件表预览 移除版本控制操作 // 删除文件的命令 $ git rm -r --cached "bin/" //提交,并加注释. $ git commit -m" 删除bin文件" //提交到远程服务器 $ git push origin master 当我们需要删除暂存区或分支上的文件, 但本地又需要使用, 只是不希望这个文件被版本控制, 可以使用 git rm --cached file_path git commit -m 'delete remote […]

Apache虚拟主机配置

将这个配置与 Nginx 配置https并反向代理多台服务器一起使用效果更好.肯定要问我为什么不直接用Nginx提供web服务?我能告诉你的是,我喜欢责任分离. 开始 在 /var/www/ 下创建你网站的目录,比如: mkdir blog.well-known.me 创建Virtual配置目录 mkdir /etc/httpd/sites-available mkdir /etc/httpd/sites-enabled 配置httpd.conf vi /etc/httpd/conf/httpd.conf 跳转到文档末尾添加以下内容 IncludeOptional sites-enabled/*.conf 注释掉# DocumentRoot “/var/www/html” 创建网站Virtual配置文件 vi /etc/httpd/sites-available/blog.well-known.me.conf 添加以下内容 <VirtualHost *:8000> ServerName blog.well-known.me ServerAlias blog.well-known.com DocumentRoot /var/www/blog.well-known.me </VirtualHost> <Directory "/var/www/blog.well-known.me"> Options +Includes -Indexes AllowOverride All Require all […]

提高Nginx服务器硬度的12个技巧

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。 1:保持Nginx的及时升级 目前Nginx的稳定版本为1.15.1,最好升级到最新版本.另外,虽然安装包安装比通过源代码编译安装更容易,但后一个选项有两个优点: 1)它允许您将额外的模块添加到Nginx中(如more_header,mod_security), 2)它总是提供比安装包更新的版本,在Nginx网站上可看release note。 2:去掉不用的Nginx模块 在编译安装时,执行./configure方法时加上以下配置指令,可以显式的删除不用的模块: ./configure --without-module1 --without-module2 --without-module3 例如: ./configure --without-http_dav_module --withouthttp_spdy_module 注意:配置指令是由模块提供的。确保你禁用的模块不包含你需要使用的指令!在决定禁用模块之前,应该检查Nginx文档中每个模块可用的指令列表。 3:在Nginx配置中禁用server_tokens项 server_tokens在打开的情况下会使404页面显示Nginx的当前版本号。这样做显然不安全,因为黑客会利用此信息尝试相应Nginx版本的漏洞。 只需要在nginx.conf中http模块设置server_tokens off即可,例如: server { listen 192.168.0.25:80; server_tokens off; server_name tecmintlovesnginx.com www.tecmintlovesnginx.com; access_log /var/www/logs/tecmintlovesnginx.access.log; error_log /var/www/logs/tecmintlovesnginx.error.log er […]

如何写出让同事无法维护的代码?

如何写出让同事无法维护的代码? 01. 程序命名 容易输入的变量名。 比如:Fred,asdf **单字母的变量名。**比如:a,b,c, x,y,z(如果不够用,可以考虑a1,a2,a3,a4,….) **有创意地拼写错误。**比如:SetPintleOpening, SetPintalClosing。这样可以让人很难搜索代码。 抽象。比如:ProcessData, DoIt, GetData… 抽象到就跟什么都没说一样。 **缩写。**比如:WTF,RTFSC …… (使用拼音缩写也同样给力,比如:BT,TMD,TJJTDS) **随机大写字母。**比如:gEtnuMbER.. **重用命名。**在内嵌的语句块中使用相同的变量名有奇效。 **使用重音字母。**比如:int ínt(第二个 ínt 不是 int) **使用下划线。**比如:, , 。 **使用不同的语言。**比如混用英语,德语,或是中文拼音。 **使用字符命名。**比如:slash, asterix, comma… **使用无关的单词。**比如:god, superman, iloveu…. **混淆 l 和 1。**字母 l 和数字 1 有时候是看不出来的。 02. 伪装欺诈 把注释和代码交织在一起。 for(j=0; j<array_len; j+ =8){ total += array[j+0 ]; total += array[j+1 ]; […]

Java8新特性之lambda表达式

Java8的lambda表达式也不是什么新鲜事儿了,毕竟java9都出来了那么久 了,也不是想说怎么用。只是想记录一下自己的学习的一个过程。加深一下自己,做个记录而已。 列子1 在以前如果我们开启一个线程的做法有两种,集成Thread类覆写其中run函数;实现Runnable接口覆写run函数。现在我们以实现Runnable接口为例。 new Thread(new Runnable() { @Override public void run() { System.out.println("hello world"); } }).start(); 在这里面其实我们只关心一个地方,那就是在run函数中的代码,但是我们不得不去一些其他额外的事来满足这样的语法。有了lambda以后我们有了更简洁的代码了; new Thread(()->System.out.println("hello world")).start(); 之前我们想要将行为传入函数,仅有的选择就是匿名内部类。有了lambda表达式以后,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。 列子2 匿名内部类的方式 TreeSet<String> set = new TreeSet<>(new Comparator<String>() { @Override public int compare(String str1, String str2) { return Integer.compare(str1.length(), str2.length()); } }); Lambda 方式 TreeSet<String> set2 = new TreeSet<String>((str1,str2)->Integer.compare(str1.length(), str2.length())); 新的操作符 “->”: Lambda 操作符或剪头操作符。它将 Lambda 分为 两个部分: 左侧:指定了 Lambda 表达式需要的所有参数 右侧:指定了 Lambda 体,Lambda表达式要执行的功能。 语法格式 无参,无返回值 […]

Netty4 TCP协议之自定义解码器,解决分包和粘包

socket流顾名思义它像一种流体,流体的特征是什么?不清楚它的开始和结尾嘛!TCP不了解上层业务数据的具体含义,它只会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。 好,现在我们有这样一个需求,客户端要向服务器发送两条指令分别是: ABCDE FGHIJ 那么最终我们可能会出现以下这四种情况 我们分别收到两条指令 ABCDE ***** FGHIJ 我们也能受到两条指令 ABCDEFG ***** HIJ 我们也能收到两条指令 ABC ***** DEFGHIJ 我们只能收到一条指令 ABCDEFGHIJ 当然我们肯定是希望只出现第一种情况,但是现实并没有这么美好。解决办法。。。 肯定是有的。 两种解决方法 在每发一条指令后我们加一个特殊字符来作为分割位。比如:\r\n但是这样的方式不太好,每次都要每个字节的去寻找这样的结束符,所以性能肯定不会好到哪里去。 第二种方式像下面这样 假如我们定义了一个这样的传输协议 /** * * +--------+----------+-----------+------+----------+ * | 包头 | 一级指令 | 二级指令 | 长度 | 数据 | * +--------+----------+----------+-------+----------+ * | 4byte | […]

如何创建私有CA的 SSL 证书?

1:创建 CA 私钥 $ openssl genrsa -des3 -out ca.key 4096 2:生成 CA 的自签名证书,其实 CA 证书就是一个自签名证书 $ openssl req -new -x509 -days 365 -key ca.key -out ca.crt 3:生成需要颁发证书的私钥 $ openssl genrsa -des3 -out server.key 4096 4:生成要颁发证书的证书签名请求 ** Ps:证书签名请求当中的 Common Name 必须区别于 CA 的证书里面的 Common Name $ openssl req -new -key server.key -out server.csr 5:创建一个ext文件,内容如下 keyUsage = nonRepudiation, […]