<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[你若盛开，清风自来]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/randavy</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; randavy]]></copyright><item><title><![CDATA[网络安全：给你的云主机做一次体检]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/167223908</link><guid>https://blog.youkuaiyun.com/randavy/article/details/167223908</guid><author>randavy</author><pubDate>Wed, 07 Oct 2026 19:26:28 +0800</pubDate><description><![CDATA[真正要盯的是**两件事**：**新增**（这个攻击类型/路径昨天没有，今天有了）和**成功**（攻击请求拿到 200/403 之外的"好结果"）。**为什么查**：`/tmp`、`/var/tmp`、`/dev/shm` 是全世界用户都可写的目录，也是攻击者的"落点首选"——爆破脚本、挖矿程序、提权 exploit 都习惯先放这里再执行。**防误报提示**：如果你用云厂商控制台的"一键登录 / Workbench"，会话里会出现厂商注入的**临时密钥**登录记录（来源是云控制台网段）。]]></description><category></category></item><item><title><![CDATA[一个优秀的日志应该是什么样的]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/146768004</link><guid>https://blog.youkuaiyun.com/randavy/article/details/146768004</guid><author>randavy</author><pubDate>Sun, 30 Mar 2025 16:16:12 +0800</pubDate><description><![CDATA[在上一篇"一个合格的日志应该是什么样的"，我们打印的日志已经基本可用了。在线上接口行为和预期的不一致时，INFO日志又不够详细，看不出问题。]]></description><category></category></item><item><title><![CDATA[一个合格的日志应该是什么样的]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/146728353</link><guid>https://blog.youkuaiyun.com/randavy/article/details/146728353</guid><author>randavy</author><pubDate>Sun, 30 Mar 2025 11:25:40 +0800</pubDate><description><![CDATA[参数校验失败用WARN，通过后打印参数用DEBUG级别，核心方法用INFO，调用量大时对INFO日志采样或降级为DEBUG...如果是重要接口，可以用INFO打印入参...当然为了代码美观，你可以将入参的打印逻辑用AOP封装，将参数校验的逻辑提取到专门的校验方法，自定业务异常及Assert工具返回响应。]]></description><category></category></item><item><title><![CDATA[忽略Git文件的修改，让它不被提交]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/145840386</link><guid>https://blog.youkuaiyun.com/randavy/article/details/145840386</guid><author>randavy</author><pubDate>Mon, 24 Feb 2025 22:46:49 +0800</pubDate><description><![CDATA[有的时候文件是由git托管的，但是我们希望只在本地修改，而且修改不被提交到服务端，这时候可以使用。使用Git托管的工程中，经常有这样的需求，希望文件只是本地修改，不提交到服务端。如果仅仅是本地存在的文件，我们可以通过.gitignore配置避免文件被提交。]]></description><category></category></item><item><title><![CDATA[Spring Cache的使用]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/145168426</link><guid>https://blog.youkuaiyun.com/randavy/article/details/145168426</guid><author>randavy</author><pubDate>Wed, 15 Jan 2025 21:25:14 +0800</pubDate><description><![CDATA[Spring提供了EhCache和Caffeine的默认实现，如果使用没有默认实现的Cache，可以通过自定义CacheManager来实现@Bean。]]></description><category></category></item><item><title><![CDATA[文件上传超时问题定位: 背景知识]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/144994277</link><guid>https://blog.youkuaiyun.com/randavy/article/details/144994277</guid><author>randavy</author><pubDate>Tue, 07 Jan 2025 21:43:29 +0800</pubDate><description><![CDATA[文件上传时，浏览器和服务端建立连接，读取并发送文件的内容，Servlet容器接收数据后写入本地文件，封装为对象传递给Servlet实现类。如果是Spring Cloud Gateway，可以通过如下设置，配置Gateway和后端服务器的超时时间。如果使用的是Tomcat，可以设置连接超时时间和读入超时时间。]]></description><category></category></item><item><title><![CDATA[怎么确定性能优化是真的有效？]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/143388489</link><guid>https://blog.youkuaiyun.com/randavy/article/details/143388489</guid><author>randavy</author><pubDate>Thu, 31 Oct 2024 11:16:32 +0800</pubDate><description><![CDATA[当我们做的软件即将迎接挑战的时候，我们经常会做的事情是压测，并尝试做性能优化，不过性能优化的效果有时候并不是那么的明显。假设我们对一个接口做了优化，优化前后接口的耗时分别如下图有2次是接口性能明显提供(迭代1、3)，有1次明显变差，感觉是优化成功了，而这差异可能是环境造成的，无法做一个定量的明确回答。]]></description><category></category></item><item><title><![CDATA[基于Redis实现的延迟队列]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/142860280</link><guid>https://blog.youkuaiyun.com/randavy/article/details/142860280</guid><author>randavy</author><pubDate>Fri, 11 Oct 2024 18:05:05 +0800</pubDate><description><![CDATA[我们需要做的是在程序中定时的执行这段Lua脚本，并且实现类似DelayQueue的逻辑，支持阻塞的take()操作，以及消费失败时的错误处理，显然要处理的错误细节并不少。通过[[#3. 数据消费]]的操作，redisson已经将到期的延迟任务写入到delayBlockingQueue了，剩下要做的就是用delayBlockingQueue实现阻塞队列了，核心代码在 RedissonBlockingQueue，其实实现很简单，我们来看下代码，take()方法实际只是执行了一个redis命令。]]></description><category></category></item><item><title><![CDATA[ShardingSphere导致的NPE]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/141458653</link><guid>https://blog.youkuaiyun.com/randavy/article/details/141458653</guid><author>randavy</author><pubDate>Fri, 23 Aug 2024 10:08:12 +0800</pubDate><description><![CDATA[1. 项目背景
工程内使用shardingsphere支持分库分表，上层使用的MybatisPlus，有一张表的操作总是报NullPointException。
2. 异常堆栈
### SQL: INSERT INTO t_tg_message  ( update_id, from_id, from_user_name, chat_id, type, data, text, create_time, deleted )  VALUES  ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
### C]]></description><category></category></item><item><title><![CDATA[Git仓库拆分和Merge]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/140568483</link><guid>https://blog.youkuaiyun.com/randavy/article/details/140568483</guid><author>randavy</author><pubDate>Sat, 20 Jul 2024 11:36:55 +0800</pubDate><description><![CDATA[我们原先有一个项目叫open-api，后来想要做租户独立发展，每个租户独立成一个项目，比如租户akc独立部署一个akc-open-api，租户yhd独立部署一个yhd-open-api，其中大部分代码是相同的，少量租户定制代码。上面我们从open-api项目复制了一个新的akc-open-api项目，公共的代码修我们不想重复劳动，通过修改open-api，再通过跨项目合并到不同的租户下。这一节的目的是从open-api复制一个新项目称为akc-open-api，操作步骤如下。关联open-api的仓库。]]></description><category></category></item><item><title><![CDATA[Maven报错 NullPointerException as JavaCompiler.readSourceFile]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/140363732</link><guid>https://blog.youkuaiyun.com/randavy/article/details/140363732</guid><author>randavy</author><pubDate>Thu, 11 Jul 2024 22:32:13 +0800</pubDate><description><![CDATA[我这的问题的原因是在Maven使用的Java和工程使用的Java版本问题，全局环境变量设置的Java版本为Java 11，而IDEA设置的是Java8，Maven配置是。修改项目的JDK版本，修改环境变量中的Java版本就能解决该问题。]]></description><category></category></item><item><title><![CDATA[GRPC使用之ProtoBuf]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/140248703</link><guid>https://blog.youkuaiyun.com/randavy/article/details/140248703</guid><author>randavy</author><pubDate>Sun, 07 Jul 2024 17:00:41 +0800</pubDate><description><![CDATA[Protocol Buffers提供一种跨语言的结构化数据的序列化能力，类似于JSON，不过更小、更快，除此以外它还能用用接口定义(IDL interface define language)，通protoc编译Protocol Buffer定义文件，生成结构化类，以及服务调用的客户端和服务端。除此以外，proto允许用户自己通过message、enum定义自己的类型，比如之前提到的Person，我们再看一下示例。]]></description><category></category></item><item><title><![CDATA[GRPC使用之HelloWorld]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/140203224</link><guid>https://blog.youkuaiyun.com/randavy/article/details/140203224</guid><author>randavy</author><pubDate>Fri, 05 Jul 2024 11:15:40 +0800</pubDate><description><![CDATA[先通过mvn archetype:generate从quickstart生成一个极简的Maven项目引入grpc的Maven依赖以及打包插件，插件略复杂，主要的目的是为了将grpc生成的代码直接打包进当前工程的jar，暂时忽略具体含义即可。]]></description><category></category></item><item><title><![CDATA[SpringBoot: Eureka入门]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/140069526</link><guid>https://blog.youkuaiyun.com/randavy/article/details/140069526</guid><author>randavy</author><pubDate>Sat, 29 Jun 2024 20:00:18 +0800</pubDate><description><![CDATA[服务提供者在启动的时候会将自己注册到服务注册中心(zookeeper、consul等实现)，服务消费者从注册中心拿到服务提供者的IP，在客户端做负载均衡，直接连接服务提供者的IP，相较于反向代理的方案好处是服务A和服务B是直接调用，避免了一次中间转发。最简单的方法是让服务A配置服务B的所有节点的IP，在服务A内部做负载均衡调用服务B的不同节点。我们先来看看Eureka的使用。我们需要将服务B的节点配置为upstream，定义nginx的server，服务A通过nginx调用服务B，我们看看下面的核心配置。]]></description><category></category></item><item><title><![CDATA[Java核心: JarIndex的使用]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139576030</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139576030</guid><author>randavy</author><pubDate>Mon, 10 Jun 2024 13:42:56 +0800</pubDate><description><![CDATA[在讲解的时候，我们发现URLClassLoader加载类或资源时通过访问ClassPath下的每一个路径，来确定类是否存在的，假设我们执行的命令是这样的如果我们代码里使用了org.springframework.boot.loader.launch.Archive，我们的类加载器会依次尝试在每个ClassPath下每个元素一个复杂的大型项目依赖几十个上百个第三方jar是很常见的，总是这么查找显然是极其低效的。]]></description><category></category></item><item><title><![CDATA[Java核心: 类加载器]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139567554</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139567554</guid><author>randavy</author><pubDate>Sun, 09 Jun 2024 22:52:34 +0800</pubDate><description><![CDATA[这一节我们来学习Java的类加载器，以及常用的类加载器实现URLClassLoader。]]></description><category></category></item><item><title><![CDATA[SpringBoot: 启动流程和类装载]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139567167</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139567167</guid><author>randavy</author><pubDate>Sun, 09 Jun 2024 22:26:46 +0800</pubDate><description><![CDATA[前面我们学过Spring定制了自己的可执行jar，将真正执行时需要的类和依赖放到BOOT-INF/classes、BOOT-INF/lib来，为了能够识别这些为止的源文件，Spring定制了自己类加载器，本节我们来讲解这个类加载器。]]></description><category></category></item><item><title><![CDATA[SpringBoot: 可执行jar的特殊逻辑]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139547654</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139547654</guid><author>randavy</author><pubDate>Sat, 08 Jun 2024 16:12:44 +0800</pubDate><description><![CDATA[这一篇我们来看看Java代码怎么操作zip文件(jar文件)，然后SpringBoot的特殊处理，文章分为2部分。]]></description><category></category></item><item><title><![CDATA[Java核心: 为图片生成水印]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139510585</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139510585</guid><author>randavy</author><pubDate>Thu, 06 Jun 2024 21:45:38 +0800</pubDate><description><![CDATA[今天干了一件特别不务正业的事，做了一个小程序用来给图片添加水印。事情的起因是有人管我要身份证照片，手边并没有一个趁手的工具来生成图片水印。很多APP提供了水印的功能，但会把我的图片上传到他们的服务器，身份证太敏感了，显然我并不想让别人有机会保留照片。我把图片处理做了一个抽象，入参是BufferedImage，对图片添加水印、盲印、隐式写入后返回新的BufferedImage作为结果。]]></description><category></category></item><item><title><![CDATA[SpringBoot: 读取项目的Git版本号]]></title><link>https://blog.youkuaiyun.com/randavy/article/details/139481816</link><guid>https://blog.youkuaiyun.com/randavy/article/details/139481816</guid><author>randavy</author><pubDate>Wed, 05 Jun 2024 20:58:34 +0800</pubDate><description><![CDATA[在开发项目的时候，我们经常会想要拿到线上运行的程序版本，以确定程序是否正确发布。Spring Boot提供了这样的能力支持。]]></description><category></category></item></channel></rss>