👋 欢迎来到我的空间!
- 这里是我的个人博客,记录了一些技术、生活、读书、随笔等内容。 如果你喜欢这里,可以点击右上角的 Github 图标。 如果你有任何问题或建议,欢迎在评论区留言。 email: hi@qvqw.date
👋 欢迎来到我的空间!
从大学生到办公室的牛马,已经半年多了。 我的确还是很喜欢计算机喜欢折腾,但是和大学相比没有那么多的时间和精力了。有时我也会感觉,上班让我失去了对计算机的兴趣。后来我发现不是的,我只是不喜欢工作罢了,当我有时间去做自己的事情时,我还是很享受折腾计算机的乐趣。 我觉得除了工作的任务,是需要有一些时间来学习新的技术,尝试新的内容。在摸鱼时进步,在摸鱼时提高。不需要什么准备,有想法直接开始做。希望我的技术,在2025能有更大的提高,加油!
最近考虑买一台MacBook Pro,当作新的生产力。但是目前的开发又离不开X86的windows平台,考虑使用mac进行代码开发运行,使用windows进行调试。项目中用到的数据库以及第三方的接口需要使用vpn访问内网,且vpn只能登录一个设备,所以考虑在windows上登录vpn,系统运行需要用到的数据库以及第三方接口都使用windows电脑进行转发。 数据库转发(转发tcp) 我用的是windows自带的portproxy功能 使用以下命令即可实现端口转发 netsh interface portproxy add v4tov4 listenport=[监听端口号] listenaddress=[本地IP地址] connectport=[目标端口号] connectaddress=[目标IP地址] 验证端口转发是否配置成功 netsh interface portproxy show all 如果想删除某个端口转发规则 netsh interface portproxy delete v4tov4 listenport=[监听端口号] listenaddress=[本地IP地址] 第三方接口转发 我使用的是caddy代理,只需要一行命令即可 caddy reverse-proxy --from 本机ip --to 第三方接口的内网ip 踩坑 尝试过让windows登vpn,然后开热点给另一个电脑。经测试另一台电脑连上热点只能访问外网,查资料说windows的个人热点直接走物理网卡转发,不会走代理。 尝试用caddy代理数据库的tcp连接,理论上可以使用caddy的第三方模块实现代理tcp,但是没有研究明白,放弃了,感觉caddy还是代理http请求更合适一些。 结尾 目前只是做了数据库以及第三方接口的代理,等过一段时间买到新电脑了,再继续折腾。生命不息息,折腾不止😂
Chatgpt对ip有较为严格的限制,使用Cloudflare WARP可以隐藏服务器的真实ip,解除访问限制。 安装Cloudflare WARP 官方文档 # Add cloudflare gpg key curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg # Add this repo to your apt repositories echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list # Install sudo apt-get update && sudo apt-get install cloudflare-warp 设置cloudflare warp 一定要把mode设置为proxy,然后连接。否则将无法使用ssh访问服务器。 warp-cli registration new #注册 warp-cli mode proxy # 设置代理模式为socks代理 warp-cli proxy port 40000 #设置代理端口40000 warp-cli connect # 连接 xray配置 inbounds 要开启 sniffing...
正式系统无法访问外网,测试系统可以访问外网。正式系统的一个SDK需要向外网发送HTTP请求,考虑使用sni 代理。 软件 gost 参考文档 部署 能联网的测试机使用docker compose部署(设置xxx.com的sni代理白名单,xxx.com前面的~表示白名单,不加~表示黑名单) services: gost: image: gogost/gost container_name: gost ports: - "80:80" command: -L sni://:80?bypass=~xxx.com restart: unless-stopped 不能联网的正式机配置/etc/hosts 测试机ip xxx.com 我的后端是容器部署的,然后给容器配置/etc/hosts文件映射就可以了 注意 不能在构建docker image时候修改hosts,只能在容器运行时进行映射或者修改。因为构建阶段/etc/hosts是只读的。image是许多只读layer的叠加,而容器是只读layer和可读layer的叠加
最近使用一个第三方的SDK来请求数据,但是请求的服务器对ip有白名单限制,SDK使用的apache的commons-httpclient: 3.1 发送请求。于是尝试使用ApectJ运行时织入,拦截发送HTTP请求的代码,修改参数. 依赖(用的1.9.19版本) <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> maven插件 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> 切面 import org.apache.commons.httpclient.HttpMethod; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class HttpClientAspect { public static HttpClientAspect aspectOf() { return new HttpClientAspect(); } @Around("execution(* org.apache.commons.httpclient.HttpClient.executeMethod(..))") public Object aroundHttpExecution(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("======================================"); Object[] args = joinPoint.getArgs(); // 获取HttpMethod参数 if (args != null && args....
当你使用 // 1. 创建或加载 ResourceBundle ResourceBundle bundle = ResourceBundle.getBundle("messages"); // 从 classpath 加载 messages.properties // 2. 使用getString()获取字符串值 String value = bundle.getString("key.name"); 读取文件时 代码默认会读取src/main/resources/messages.properties src/main/resources/messages.properties // 默认 src/main/resources/messages_zh.properties // 中文 src/main/resources/messages_en.properties // 英文 样例配置文件 key.name=值 welcome.message=欢迎 error.code=500 如果想指定读取的文件 // 指定英文 Locale Locale enLocale = new Locale("en"); // 或者直接用 Locale.ENGLISH // 加载英文资源包 ResourceBundle bundle = ResourceBundle.getBundle("messages", enLocale); // 获取英文值 String value = bundle.getString("key.name");
最近在做一个消息推送企业某信的需求,使用的不是官方的api,而是和企业某信可以集成的云办公平台的api。由于api有ip白名单限制,导致我必须在特定化网络环境下发请求,测试很麻烦,所以想测试一下能不能绕过限制。 想要绕过限制,首先要知道服务器如何获取发送者的ip。 服务器如何获取请求者ip 获取请求者 IP 本质上就两个来源: 直接从 IP 数据包获取 这就是 HttpServletRequest的getRemoteAddr() 的工作原理,获取的是直接与服务器建立 TCP 连接的客户端 IP,在没有代理的情况下,这就是真实的客户端 IP 从 HTTP 请求头获取 常见的请求头有: X-Forwarded-For X-Real-IP Proxy-Client-IP WL-Proxy-Client-IP 测试 这里我使用了postman伪造了请求头X-Forwarded-For,经过测试,理论上只要知道正确的ip,就可以让ip白名单功能失效。 如果你有服务器的访问权限,但是只知道服务器的内网ip,可以尝试 curl ifconfig.me 然后就能得到服务器的公网ip了 安全建议 改用网络层的源IP地址(TCP/IP报文中的source IP)进行验证 如果必须使用代理转发,建议只信任内部代理服务器传递的XFF头 吐槽 某云办公平台必须付费才能获得访问api的密钥,并且密钥只有一个,测试只能直接在正式系统测
目前使用hugo作为博客系统,使用typora作为博客的编辑器。书接上文Hugo使用技巧,之前每次都需要在博客根目录执行 hugo new posts/文章标题/index.md 创建新的文章。感觉很麻烦。所以想写个工具简化这个过程。 思路 输入文件标题后执行创建文章的命令,然后生成新的文章的快捷方式,方便使用typora进行编辑。 代码 使用Claude生成的,很方便。 如果是windows平台,使用 go build -o HugoHelper.exe main.go 进行编译。 使用前需要配置blog环境变量,key为blog,value为你的项目的根路径 比如我的根目录是C:\UGit\qvqw.date 代码 package main import ( "bufio" "fmt" "os" "os/exec" "path/filepath" "strings" ) func main() { // 获取当前程序执行路径 execPath, err := os.Getwd() if err != nil { fmt.Printf("错误: 获取当前路径失败: %v\n", err) os.Exit(1) } // 从环境变量获取博客路径 blogPath := os.Getenv("blog") if blogPath == "" { fmt.Println("错误: 环境变量 'blog' 未设置") os.Exit(1) } // 验证博客路径是否存在 if _, err := os....
非原创,原文地址https://github.com/CodingDocs/springboot-guide/blob/master/docs/basis/springboot-jpa.md JPA 这部分内容上手很容易,但是涉及到的东西还是挺多的,网上大部分关于 JPA 的资料都不是特别齐全,大部分用的版本也是比较落后的。另外,我下面讲到了的内容也不可能涵盖所有 JPA 相关内容,我只是把自己觉得比较重要的知识点总结在了下面。我自己也是参考着官方文档写的,官方文档非常详细了,非常推荐阅读一下。这篇文章可以帮助对 JPA 不了解或者不太熟悉的人来在实际项目中正确使用 JPA。 项目代码基于 Spring Boot 最新的 2.1.9.RELEASE 版本构建(截止到这篇文章写完),另外,新建项目就不多说了,前面的文章已经很详细介绍过。 1.相关依赖 我们需要下面这些依赖支持我们完成这部分内容的学习: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> 2.配置数据库连接信息和JPA配置 由于使用的是 h2 内存数据库,所以你直接运行项目数据库就会自动创建好。 下面的配置中需要单独说一下 spring.jpa.hibernate.ddl-auto=create这个配置选项。 这个属性常用的选项有四种: create:每次重新启动项目都会重新创新表结构,会导致数据丢失 create-drop:每次启动项目创建表结构,关闭项目删除表结构 update:每次启动项目会更新表结构 validate:验证表结构,不对数据库进行任何更改 但是,一定要不要在生产环境使用 ddl 自动生成表结构,一般推荐手写 SQL 语句配合 Flyway 来做这些事情。 # 数据库url地址 spring.datasource.url=jdbc:h2:mem:jpa-demo spring.datasource.username=root spring.datasource.password=123456 spring.datasource.platform=h2 spring.datasource.driverClassName =org.h2.Driver spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true # 打印出 sql 语句 spring....
使用 cpolar 为 rock 5A 进行内网穿透 github 上有开源的 frp 项目,如果有一台云服务器的话,用来内网穿透很不错。但是,使用云服务+frp 的方案,开放某个端口,还需要去修改云服务的安全组,比较麻烦。考虑到方便性,我用了 cpolar 做内网穿透。 注:rock 5A 为 arm 开发板,系统为 debian12(和树莓派、香橙派等 arm 计算机的教程理论上通用) 安装 我这里使用的官方的一键安装脚本 curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash 授权 执行下面 的命令进行授权(授权码在 cpolar 验证页面获取) cpolar authtoken xxxxxxxxxxxxxxxxxx 设置开机自启动并启动 cpolar 服务 systemctl enable cpolar systemctl start cpolar 完成上面的内容就基本上配置好了,你可以在 cpolar 官网的状态页面看到你的 ssh 隧道,可以通过该域名和端口远程访问本地的 rock 5A 注意:cpolar 默认会配置本地机器 ssh 的 内网穿透,如需定制自己的内网穿透,请尝试根据官网文档修改配置文件。免费的内网穿透会在机器重启后变更域名和端口,重启后可以从 cpolar 官网状态页面获取,也可以考虑升级付费用户。 配置文件 默认的配置文件在 /usr/local/etc/cpolar/cpolar.yml 补充说明 使用过程中,我发现 cpolar 代理 http 导致了 rock 5A 的 cpu 占用飙升。后续我用了阿里云的服务器+frp 代理了 ssh,cloudflare tunnel 代理 http,cpu 占用几乎忽略不计。因此,建议 cpolar 内网穿透方案仅作备选。