# Technical Documentation: fuzhengwei/CodeGuide

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/fuzhengwei/CodeGuide)

### Overview (README.md)

# CodeGuide | 程序员编码指南

> 你好，我是小傅哥，[《重学Java设计模式》](https://item.jd.com/13218336.html) 图书作者，一线互联网 Java 工程师、架构师。[:pencil2: 虫洞栈，博主](https://bugstack.cn)，[:memo: 关于我](https://bugstack.cn/md/other/guide-to-reading.html) 

- :dog: 13年毕业，大厂互联网T8架构师，全网40万粉编程知识博主。
- :man_technologist: 成长：[关于我，从小白到架构师的成长经历](https://www.bilibili.com/video/BV1FF41137q5)
- :bus: 源码：[`RoadMap 编程路书`](https://github.com/fuzhengwei/RoadMap) | [`Java 数据结构和算法`](https://github.com/fuzhengwei/java-algorithms) | [`IM 仿微信`](https://github.com/fuzhengwei/NaiveChat) | [`Java 面经手册`](https://github.com/fuzhengwei/interview) | [`IntelliJ IDEA 插件开发`](https://github.com/fuzhengwei/guide-idea-plugin) | [`Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践`](https://github.com/fuzhengwei/Lottery) | [`API网关`](https://github.com/fuzhengwei/api-gateway) | [`手写MyBatis`](https://github.com/fuzhengwei/small-mybatis) | [`重学Java设计模式`](https://github.com/fuzhengwei/itstack-demo-design) | [`Netty 实战案例`](https://github.com/fuzhengwei/itstack-demo-netty) | [`字节码编程`](https://github.com/fuzhengwei/itstack-demo-bytecode) | [`ChatGPT AI 问答助手`](https://github.com/fuzhengwei/chatbot-api) | [更多搜索...](https://github.com/fuzhengwei?tab=repositories)
- :seedling: 干货：[公众号『 bugstack虫洞栈 』](https://bugstack.cn/images/personal/qrcode.png)
- :pencil: 博客：[bugstack.cn](https://bugstack.cn/) - 足够硬核，内容老狠了！
- :tv: 视频：[B站 小傅哥の码场](https://space.bilibili.com/15637440)
- :love_letter: 微信：[fustack](https://bugstack.cn/images/personal/fustack.png) - 备注来意
- :feet: 我的编程知识星球：[实战生产级项目、手写框架级源码，可以向我 1对1 提问，解答技术/职场/规划问题](https://bugstack.cn/md/zsxq/introduce.html)

<br/>
<div align="center">
    <a href="https://bugstack.cn" style="text-decoration:none"><img src="https://bugstack.cn/images/system/CodeGuide-LOGO.png?raw=true" width="256px"></a>
</div>
<br/>

<div align="center">
	<a href="https://bugstack.cn/md/other/guide-to-reading.html"><img src="https://bugstack.cn/images/system/CodeGuide-Read.svg"></a>
	<a href="https://bugstack.cn/images/personal/qrcode.png"><img src="https://bugstack.cn/images/system/CodeGuide-WeiXinCode.svg"></a>
	<a href="https://bugstack.cn/md/knowledge/pdf/2021-01-26-Java%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8CPDF%E4%B8%8B%E8%BD%BD.html"><img src="https://bugstack.cn/images/system/CodeGuide-JavaPDF.svg"></a>
	<a href="https://mp.weixin.qq.com/s/VthCUlT8oAJqKOoq5_NzSQ"><img src="https://bugstack.cn/images/system/CodeGuide-Lottery.svg"></a>
	<a href="https://github.com/fuzhengwei/CodeGuide"><img src="https://badgen.net/github/stars/fuzhengwei/CodeGuide?icon=github&color=4ab8a1"></a>
</div>

<br/>  
     
<div align="center">
    <p align="center"><b>知识星球</b>：<a href="https://t.zsxq.com/jAi2nUf">码农会锁</a> 👇</p>
   <table>
  		<tbody>
            <tr>
               <td align="center" valign="middle">
                <a href="https://t.zsxq.com/jAi2nUf"><img src="https://bugstack.cn/images/system/CodeGuide-xingqiu-3.png" width="900px"></a>
              </td>       
            </tr>
  		</tbody>
	</table>
</div>

1. **介绍**：关于 虫洞栈 · CodeGuide 的相关介绍请看：[关于`虫洞栈`的一些说明](https://bugstack.cn/md/other/guide-to-reading.html)
2. **贡献**：欢迎参与到 CodeGuide 的维护工作，你可以 `提交Issue`、`处理Issue`、`提交PR(Fork代码库，提交Pull requests) - 另外当你 Fork 代码库后，可以在阅读` [`bugstack.cn`](https://bugstack.cn/) 时，文末点击 “在 GitHub 上编辑此页” 进行提交PR Go -> [操作指导](https://github.com/fuzhengwei/CodeGuide/issues/260)
3. **PDF**：[《Java 面经手册》](https://download.csdn.net/download/Yao__Shun__Yu/14932325)、[《字节码编程》](https://download.csdn.net/download/Yao__Shun__Yu/12505051)
4. **小册**：[IM](https://blog.csdn.net/generalfu/category_10400631.html) - Netty4.x + SpringBoot 仿PC微信、[SpringBoot 中间件设计和开发](https://juejin.cn/book/6940996508632219689) - 16个中间件实现，包括测试工程等共计30个代码库，每一章节都会对应有一个中间件的设计和实现
5. **我的书籍**：[《重学Java设计模式》](https://item.jd.com/13218336.html) - 这是一本基于互联网真实案例编写的Java设计模式实践图书。全书以解决方案为核心，从实际开发业务中抽离出交易、营销、规则引擎、中间件、框架源码等22个真实场景，对设计模式进行全面、彻底的分析。
6. **知识星球**：[码农会锁](https://t.zsxq.com/jAi2nUf) - 技术解答/简历批阅/成长指导/内容分享/实战项目 - [《Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践》](https://bugstack.cn/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.html)
7. **转载须知** ：以下所有文章如非文首说明皆为我（小傅哥）的原创，转载在文首注明出处，如发现恶意抄袭/搬运，会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境！⛽️

## ⛳ 目录

1. [源码](https://github.com/fuzhengwei/CodeGuide#1-%E6%BA%90%E7%A0%81) - :octocat: 公众号：[`bugstack虫洞栈`](https://bugstack.cn/images/personal/qrcode.png) 文章所涉及到的全部开源代码
2. [Java](https://github.com/fuzhengwei/CodeGuide#2-java)
    - [2.1 面经手册](https://github.com/fuzhengwei/CodeGuide#21-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)  `涵盖：数据结构、算法逻辑、并发编程、JVM、面试现场`
    - [2.2 用Java实现JVM](https://github.com/fuzhengwei/CodeGuide#22-%E7%94%A8java%E5%AE%9E%E7%8E%B0jvm---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [2.3 基础技术](https://github.com/fuzhengwei/CodeGuide#23-%E5%9F%BA%E7%A1%80%E6%8A%80%E6%9C%AF---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
3. [Spring](https://github.com/fuzhengwei/CodeGuide#3-spring)
    - [3.1 Spring 手撸专栏](https://github.com/fuzhengwei/CodeGuide#31-spring-%E6%89%8B%E6%92%B8%E4%B8%93%E6%A0%8F----%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [3.2 Mybatis 手撸专栏](https://github.com/fuzhengwei/CodeGuide#32-mybatis-%E6%89%8B%E6%92%B8%E4%B8%93%E6%A0%8F----%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [3.3 Spring Cloud](https://github.com/fuzhengwei/CodeGuide#32-spring-cloud---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [3.4 源码分析(Mybatis、Quartz)](https://github.com/fuzhengwei/CodeGuide#33-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90mybatisquartz---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
4. [面向对象](https://github.com/fuzhengwei/CodeGuide#4-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1)
    - [4.1 设计模式](https://github.com/fuzhengwei/CodeGuide#41-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [4.2 系统架构](https://github.com/fuzhengwei/CodeGuide#42-%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [4.3 开发规范&事故](https://github.com/fuzhengwei/CodeGuide#43-%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83%E4%BA%8B%E6%95%85---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
5. [中间件](https://github.com/fuzhengwei/CodeGuide#5-%E4%B8%AD%E9%97%B4%E4%BB%B6)
    - [5.1 SpringBoot 中间件开发](https://github.com/fuzhengwei/CodeGuide#51-springboot-%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%BC%80%E5%8F%91---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [5.2 IDEA-Plugin](https://github.com/fuzhengwei/CodeGuide#52-idea-plugin---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
6. [Netty 4.x](https://github.com/fuzhengwei/CodeGuide#6-netty-4x)
    - [6.1 基础入门篇](https://github.com/fuzhengwei/CodeGuide#61-%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [6.2 中级拓展篇](https://github.com/fuzhengwei/CodeGuide#62-%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [6.3 高级应用篇](https://github.com/fuzhengwei/CodeGuide#63-%E9%AB%98%E7%BA%A7%E5%BA%94%E7%94%A8%E7%AF%87---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [6.4 源码分析篇](https://github.com/fuzhengwei/CodeGuide#64-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
7. [字节码编程](https://github.com/fuzhengwei/CodeGuide#7-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B)
    - [7.1 框架](https://github.com/fuzhengwei/CodeGuide#71-%E6%A1%86%E6%9E%B6---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [7.2 全链路监控](https://github.com/fuzhengwei/CodeGuide#72-%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [7.3 文档(ASM-DOC)](https://github.com/fuzhengwei/CodeGuide#73-%E6%96%87%E6%A1%A3asm-doc---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
8. [💯实战项目](https://github.com/fuzhengwei/CodeGuide#8-%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE)
    - [IM Netty 仿PC端微信](https://github.com/fuzhengwei/CodeGuide#81-im-netty-%E4%BB%BFpc%E7%AB%AF%E5%BE%AE%E4%BF%A1---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)    
    - [SpringBoot 中间件设计和开发](https://github.com/fuzhengwei/CodeGuide#82-springboot-%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)    
    - [Lottery 分布式抽奖系统](https://github.com/fuzhengwei/CodeGuide#83-lottery-%E5%88%86%E5%B8%83%E5%BC%8F%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB) - `基于领域驱动设计的四层架构实践`   
9. [部署 Dev-Ops](https://github.com/fuzhengwei/CodeGuide#8-%E9%83%A8%E7%BD%B2---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)    
10. [📚PDF 下载](https://github.com/fuzhengwei/CodeGuide#10-pdf-%E4%B8%8B%E8%BD%BD)
11. [关于](https://github.com/fuzhengwei/CodeGuide#8-%E5%85%B3%E4%BA%8E)
    - [9.1 关于自己](https://github.com/fuzhengwei/CodeGuide#91-%E5%85%B3%E4%BA%8E%E8%87%AA%E5%B7%B1---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [9.2 关于学习](https://github.com/fuzhengwei/CodeGuide#92-%E5%85%B3%E4%BA%8E%E5%AD%A6%E4%B9%A0---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
    - [9.3 关于工作](https://github.com/fuzhengwei/CodeGuide#93-%E5%85%B3%E4%BA%8E%E5%B7%A5%E4%BD%9C---%E5%9C%A8%E7%BA%BF%E9%98%85%E8%AF%BB)
12. [转载分享](https://github.com/fuzhengwei/CodeGuide#10-%E8%BD%AC%E8%BD%BD%E5%88%86%E4%BA%AB) 
13. [参与贡献](https://github.com/fuzhengwei/CodeGuide#11-%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE) 🍁 `留下你的学习的Issue、PR，与同好同行、共同成长`
14. [与我联系](https://github.com/fuzhengwei/CodeGuide#12-%E4%B8%8E%E6%88%91%E8%81%94%E7%B3%BB) 🐾 `加入拥有技术初心纯粹的交流群`
15. [:rose: 致谢](https://github.com/fuzhengwei/CodeGuide#13-%E8%87%B4%E8%B0%A2)   

## 1. 源码

1. `Netty 4.x 专题` [itstack-demo-netty](https://github.com/fuzhengwei/itstack-demo-netty)、[网络调试助手 NetAssist](https://download.csdn.net/download/yao__shun__yu/11835105)
2. `手写RPC框架` [itstack-demo-rpc](https://github.com/fuzhengwei/itstack-demo-rpc)
3. `用Java实现JVM` [itstack-demo-jvm](https://github.com/fuzhengwei/itstack-demo-jvm)
4. `基于JavaAgent的全链路监控` [itstack-demo-agent](https://github.com/fuzhengwei/itstack-demo-agent)
5. `iot-gateway网关案例` [itstack-demo-iot-gatewary](https://github.com/fuzhengwei/itstack-demo-iot-gatewary)
6. `DDD领域驱动设计落地` [itstack-demo-ddd](https://github.com/fuzhengwei/itstack-demo-ddd)
7. `SpringCloud入门案例` [itstack-demo-springcloud](https://github.com/fuzhengwei/itstack-demo-springcloud)
8. `微信公众号开发` [itstack-ark-wx-test](https://github.com/fuzhengwei/itstack-ark-wx-test) 
9. `SpringBoot中间件开发` [door-spring-boot-starter](https://github.com/fuzhengwei/door-spring-boot-starter) 
10. `服务框架搭建` [itstack-demo-frame](https://github.com/fuzhengwei/itstack-demo-frame) 
11. `源码分析(Spring、Mybatis、Schedule)` [itstack-demo-code](https://github.com/fuzhengwei/itstack-demo-code)
12. `Drools规则引擎` [itstack-demo-drools](https://github.com/fuzhengwei/itstack-demo-drools)
13. `ASM字节码编程` [itstack-demo-asm](https://github.com/fuzhengwei/itstack-demo-asm)、[SQM](https://github.com/WormholePistachio/SQM)
14. `我的大学四年到毕业工作5年的学习资源和面试汇总` [网盘下载，if链接失效，加微信：fustack](https://pan.baidu.com/s/4mmX7sDy)
15. `Netty+JavaFx实战：仿桌面版微信聊天` [NaiveChat](https://github.com/fuzhengwei/NaiveChat) 
16. `JDK1.8新特性41个案例讲解` [itstack-demo-jdk8](https://github.com/fuzhengwei/itstack-demo-jdk8) 
17. `小傅哥的《字节码编程》专栏` [itstack-demo-bytecode](https://github.com/fuzhengwei/itstack-demo-bytecode)
18. 🔥`重学Java设计模式` [itstack-demo-design](https://github.com/fuzhengwei/itstack-demo-design) 
19. 🔥`Java面经手册` [interview](https://github.com/fuzhengwei/interview)
20. 🔥`Spring手撸专栏` [small-spring](https://github.com/fuzhengwei/small-spring)
21. `IntelliJ IDEA 插件开发` [guide-idea-plugin](https://github.com/fuzhengwei/guide-idea-plugin)
22. 🔥`Mybatis手撸专栏` [small-mybatis](https://github.com/fuzhengwei/small-mybatis)
23. `Java数据结构和算法` [java-algorithms](https://github.com/fuzhengwei/java-algorithms)

**如果**，以上某些资源不能下载获取，可以添加作者好友：小傅哥的微信(fustack)

## 2. Java

### 2.1 面经手册 - 👉[**在线阅读**](https://bugstack.cn/md/java/interview/2020-07-28-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E5%BC%80%E7%AF%87%E3%80%8A%E9%9D%A2%E8%AF%95%E5%AE%98%E9%83%BD%E9%97%AE%E6%88%91%E5%95%A5%E3%80%8B.html)

- 第 1 章 谈谈面试

    - [面经手册 · 开篇《面试官都问我啥》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-07-28-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E5%BC%80%E7%AF%87%E3%80%8A%E9%9D%A2%E8%AF%95%E5%AE%98%E9%83%BD%E9%97%AE%E6%88%91%E5%95%A5%E3%80%8B.md)
    - [面经手册 · 第1篇《认知自己的技术栈盲区》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-07-30-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC1%E7%AF%87%E3%80%8A%E8%AE%A4%E7%9F%A5%E8%87%AA%E5%B7%B1%E7%9A%84%E6%8A%80%E6%9C%AF%E6%A0%88%E7%9B%B2%E5%8C%BA%E3%80%8B.md)
    - [面试现场：小伙伴美团一面的分享和分析[含解答]](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-03-07-%E9%9D%A2%E8%AF%95%E7%8E%B0%E5%9C%BA%EF%BC%9A%E5%B0%8F%E4%BC%99%E4%BC%B4%E7%BE%8E%E5%9B%A2%E4%B8%80%E9%9D%A2%E7%9A%84%E5%88%86%E4%BA%AB%E5%92%8C%E5%88%86%E6%9E%90%5B%E5%90%AB%E8%A7%A3%E7%AD%94%5D.md)

- 第 2 章 数据结构和算法

    - [面经手册 · 第2篇《数据结构，HashCode为什么使用31作为乘数？》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-04-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC2%E7%AF%87%E3%80%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%8CHashCode%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A831%E4%BD%9C%E4%B8%BA%E4%B9%98%E6%95%B0%EF%BC%9F%E3%80%8B.md)
    - [面经手册 · 第3篇《HashMap核心知识，扰动函数、负载因子、扩容链表拆分，深度学习》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-07-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC3%E7%AF%87%E3%80%8AHashMap%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86%EF%BC%8C%E6%89%B0%E5%8A%A8%E5%87%BD%E6%95%B0%E3%80%81%E8%B4%9F%E8%BD%BD%E5%9B%A0%E5%AD%90%E3%80%81%E6%89%A9%E5%AE%B9%E9%93%BE%E8%A1%A8%E6%8B%86%E5%88%86%EF%BC%8C%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E3%80%8B.md)
    - [面经手册 · 第4篇《HashMap数据插入、查找、删除、遍历，源码分析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-13-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC4%E7%AF%87%E3%80%8AHashMap%E6%95%B0%E6%8D%AE%E6%8F%92%E5%85%A5%E3%80%81%E6%9F%A5%E6%89%BE%E3%80%81%E5%88%A0%E9%99%A4%E3%80%81%E9%81%8D%E5%8E%86%EF%BC%8C%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E3%80%8B.md)
    - [面经手册 · 第5篇《看图说话，讲解2-3平衡树「红黑树的前身」》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-16-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC5%E7%AF%87%E3%80%8A%E7%9C%8B%E5%9B%BE%E8%AF%B4%E8%AF%9D%EF%BC%8C%E8%AE%B2%E8%A7%A32-3%E5%B9%B3%E8%A1%A1%E6%A0%91%E3%80%8C%E7%BA%A2%E9%BB%91%E6%A0%91%E7%9A%84%E5%89%8D%E8%BA%AB%E3%80%8D%E3%80%8B.md)
    - [面经手册 · 第6篇《带着面试题学习红黑树操作原理，解析什么时候染色、怎么进行旋转、与2-3树有什么关联》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-20-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC6%E7%AF%87%E3%80%8A%E5%B8%A6%E7%9D%80%E9%9D%A2%E8%AF%95%E9%A2%98%E5%AD%A6%E4%B9%A0%E7%BA%A2%E9%BB%91%E6%A0%91%E6%93%8D%E4%BD%9C%E5%8E%9F%E7%90%86%EF%BC%8C%E8%A7%A3%E6%9E%90%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E6%9F%93%E8%89%B2%E3%80%81%E6%80%8E%E4%B9%88%E8%BF%9B%E8%A1%8C%E6%97%8B%E8%BD%AC%E3%80%81%E4%B8%8E2-3%E6%A0%91%E6%9C%89%E4%BB%80%E4%B9%88%E5%85%B3%E8%81%94%E3%80%8B.md)
    - [面经手册 · 第7篇《ArrayList也这么多知识？一个指定位置插入就把谢飞机面晕了！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-27-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC7%E7%AF%87%E3%80%8AArrayList%E4%B9%9F%E8%BF%99%E4%B9%88%E5%A4%9A%E7%9F%A5%E8%AF%86%EF%BC%9F%E4%B8%80%E4%B8%AA%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E6%8F%92%E5%85%A5%E5%B0%B1%E6%8A%8A%E8%B0%A2%E9%A3%9E%E6%9C%BA%E9%9D%A2%E6%99%95%E4%BA%86%EF%BC%81%E3%80%8B.md)
    - [面经手册 · 第8篇《LinkedList插入速度比ArrayList快？你确定吗？》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-08-30-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC8%E7%AF%87%E3%80%8ALinkedList%E6%8F%92%E5%85%A5%E9%80%9F%E5%BA%A6%E6%AF%94ArrayList%E5%BF%AB%EF%BC%9F%E4%BD%A0%E7%A1%AE%E5%AE%9A%E5%90%97%EF%BC%9F%E3%80%8B.md)
    - [面经手册 · 第9篇《队列是什么？什么是双端队列、延迟对列、阻塞队列，全是知识盲区！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-09-03-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC9%E7%AF%87%E3%80%8A%E9%98%9F%E5%88%97%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8C%E7%AB%AF%E9%98%9F%E5%88%97%E3%80%81%E5%BB%B6%E8%BF%9F%E5%AF%B9%E5%88%97%E3%80%81%E9%98%BB%E5%A1%9E%E9%98%9F%E5%88%97%EF%BC%8C%E5%85%A8%E6%98%AF%E7%9F%A5%E8%AF%86%E7%9B%B2%E5%8C%BA%EF%BC%81%E3%80%8B.md)
    - [面经手册 · 第10篇《扫盲java.util.Collections工具包，学习排序、二分、洗牌、旋转算法》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-09-10-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC10%E7%AF%87%E3%80%8A%E6%89%AB%E7%9B%B2java.util.Collections%E5%B7%A5%E5%85%B7%E5%8C%85%EF%BC%8C%E5%AD%A6%E4%B9%A0%E6%8E%92%E5%BA%8F%E3%80%81%E4%BA%8C%E5%88%86%E3%80%81%E6%B4%97%E7%89%8C%E3%80%81%E6%97%8B%E8%BD%AC%E7%AE%97%E6%B3%95%E3%80%8B.md)
    - [面经手册 · 第11篇《StringBuilder 比 String 快？空嘴白牙的，证据呢！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-09-17-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC11%E7%AF%87%E3%80%8AStringBuilder%20%E6%AF%94%20String%20%E5%BF%AB%EF%BC%9F%E7%A9%BA%E5%98%B4%E7%99%BD%E7%89%99%E7%9A%84%EF%BC%8C%E8%AF%81%E6%8D%AE%E5%91%A2%EF%BC%81%E3%80%8B.md)
    - [面经手册 · 第12篇《面试官，ThreadLocal 你要这么问，我就挂了！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-09-23-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC12%E7%AF%87%E3%80%8A%E9%9D%A2%E8%AF%95%E5%AE%98%EF%BC%8CThreadLocal%20%E4%BD%A0%E8%A6%81%E8%BF%99%E4%B9%88%E9%97%AE%EF%BC%8C%E6%88%91%E5%B0%B1%E6%8C%82%E4%BA%86%EF%BC%81%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br> 

- 第 3 章 并发和锁

   - [面经手册 · 第13篇《除了JDK、CGLIB，还有3种类代理方式？面试又卡住！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-10-14-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC13%E7%AF%87%E3%80%8A%E9%99%A4%E4%BA%86JDK%E3%80%81CGLIB%EF%BC%8C%E8%BF%98%E6%9C%893%E7%A7%8D%E7%B1%BB%E4%BB%A3%E7%90%86%E6%96%B9%E5%BC%8F%EF%BC%9F%E9%9D%A2%E8%AF%95%E5%8F%88%E5%8D%A1%E4%BD%8F%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第14篇《volatile 怎么实现的内存可见？没有 volatile 一定不可见吗？》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-10-21-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC14%E7%AF%87%E3%80%8Avolatile%20%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84%E5%86%85%E5%AD%98%E5%8F%AF%E8%A7%81%EF%BC%9F%E6%B2%A1%E6%9C%89%20volatile%20%E4%B8%80%E5%AE%9A%E4%B8%8D%E5%8F%AF%E8%A7%81%E5%90%97%EF%BC%9F%E3%80%8B.md)
   - [面经手册 · 第15篇《码农会锁，synchronized 解毒，剖析源码深度分析！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-10-28-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC15%E7%AF%87%E3%80%8A%E7%A0%81%E5%86%9C%E4%BC%9A%E9%94%81%EF%BC%8Csynchronized%20%E8%A7%A3%E6%AF%92%EF%BC%8C%E5%89%96%E6%9E%90%E6%BA%90%E7%A0%81%E6%B7%B1%E5%BA%A6%E5%88%86%E6%9E%90%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第16篇《码农会锁，ReentrantLock之公平锁讲解和实现》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-11-04-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC16%E7%AF%87%E3%80%8A%E7%A0%81%E5%86%9C%E4%BC%9A%E9%94%81%EF%BC%8CReentrantLock%E4%B9%8B%E5%85%AC%E5%B9%B3%E9%94%81%E8%AE%B2%E8%A7%A3%E5%92%8C%E5%AE%9E%E7%8E%B0%E3%80%8B.md)
   - [面经手册 · 第17篇《码农会锁，ReentrantLock之AQS原理分析和实践使用》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-11-11-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC17%E7%AF%87%E3%80%8A%E7%A0%81%E5%86%9C%E4%BC%9A%E9%94%81%EF%BC%8CReentrantLock%E4%B9%8BAQS%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90%E5%92%8C%E5%AE%9E%E8%B7%B5%E4%BD%BF%E7%94%A8%E3%80%8B.md)
   - [面经手册 · 第18篇《AQS 共享锁，Semaphore、CountDownLatch，听说数据库连接池可以用到！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-11-18-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC18%E7%AF%87%E3%80%8AAQS%20%E5%85%B1%E4%BA%AB%E9%94%81%EF%BC%8CSemaphore%E3%80%81CountDownLatch%EF%BC%8C%E5%90%AC%E8%AF%B4%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%8F%AF%E4%BB%A5%E7%94%A8%E5%88%B0%EF%BC%81%E3%80%8B.md) 

- 第 4 章 多线程

   - [面经手册 · 第19篇《Thread.start() ，它是怎么让线程启动的呢？》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-11-25-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC19%E7%AF%87%E3%80%8AThread.start()%20%EF%BC%8C%E5%AE%83%E6%98%AF%E6%80%8E%E4%B9%88%E8%AE%A9%E7%BA%BF%E7%A8%8B%E5%90%AF%E5%8A%A8%E7%9A%84%E5%91%A2%EF%BC%9F%E3%80%8B.md)
   - [面经手册 · 第20篇《Thread 线程，状态转换、方法使用、原理分析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-12-02-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC20%E7%AF%87%E3%80%8AThread%20%E7%BA%BF%E7%A8%8B%EF%BC%8C%E7%8A%B6%E6%80%81%E8%BD%AC%E6%8D%A2%E3%80%81%E6%96%B9%E6%B3%95%E4%BD%BF%E7%94%A8%E3%80%81%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90%E3%80%8B.md)
   - [面经手册 · 第21篇《手写线程池，对照学习ThreadPoolExecutor线程池实现原理！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-12-09-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC21%E7%AF%87%E3%80%8A%E6%89%8B%E5%86%99%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%8C%E5%AF%B9%E7%85%A7%E5%AD%A6%E4%B9%A0ThreadPoolExecutor%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第22篇《线程池的介绍和使用，以及基于jvmti设计非入侵监控》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-12-16-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC22%E7%AF%87%E3%80%8A%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E4%BB%8B%E7%BB%8D%E5%92%8C%E4%BD%BF%E7%94%A8%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%9F%BA%E4%BA%8Ejvmti%E8%AE%BE%E8%AE%A1%E9%9D%9E%E5%85%A5%E4%BE%B5%E7%9B%91%E6%8E%A7%E3%80%8B.md)

- 第 5 章 JVM 虚拟机

   - [面经手册 · 第23篇《JDK、JRE、JVM，是什么关系？》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-12-23-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC23%E7%AF%87%E3%80%8AJDK%E3%80%81JRE%E3%80%81JVM%EF%BC%8C%E6%98%AF%E4%BB%80%E4%B9%88%E5%85%B3%E7%B3%BB%EF%BC%9F%E3%80%8B.md)
   - [面经手册 · 第24篇《为了搞清楚类加载，竟然手撸JVM！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2020-12-30-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC24%E7%AF%87%E3%80%8A%E4%B8%BA%E4%BA%86%E6%90%9E%E6%B8%85%E6%A5%9A%E7%B1%BB%E5%8A%A0%E8%BD%BD%EF%BC%8C%E7%AB%9F%E7%84%B6%E6%89%8B%E6%92%B8JVM%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第25篇《JVM内存模型总结，有各版本JDK对比、有元空间OOM监控案例、有Java版虚拟机，综合学习更容易！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-01-06-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC25%E7%AF%87%E3%80%8AJVM%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B%E6%80%BB%E7%BB%93%EF%BC%8C%E6%9C%89%E5%90%84%E7%89%88%E6%9C%ACJDK%E5%AF%B9%E6%AF%94%E3%80%81%E6%9C%89%E5%85%83%E7%A9%BA%E9%97%B4OOM%E7%9B%91%E6%8E%A7%E6%A1%88%E4%BE%8B%E3%80%81%E6%9C%89Java%E7%89%88%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%8C%E7%BB%BC%E5%90%88%E5%AD%A6%E4%B9%A0%E6%9B%B4%E5%AE%B9%E6%98%93%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第26篇《JVM故障处理工具，使用总结》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-01-13-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC26%E7%AF%87%E3%80%8AJVM%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%B7%A5%E5%85%B7%EF%BC%8C%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93%E3%80%8B.md)
   - [面经手册 · 第27篇《JVM 判断对象已死，实践验证GC回收》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-01-20-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC27%E7%AF%87%E3%80%8AJVM%20%E5%88%A4%E6%96%AD%E5%AF%B9%E8%B1%A1%E5%B7%B2%E6%AD%BB%EF%BC%8C%E5%AE%9E%E8%B7%B5%E9%AA%8C%E8%AF%81GC%E5%9B%9E%E6%94%B6%E3%80%8B.md)

- 第 6 章 Spring

   - [面经手册 · 第28篇《你说，怎么把Bean塞到Spring容器》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-03-30-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC28%E7%AF%87%E3%80%8A%E4%BD%A0%E8%AF%B4%EF%BC%8C%E6%80%8E%E4%B9%88%E6%8A%8ABean%E5%A1%9E%E5%88%B0Spring%E5%AE%B9%E5%99%A8%E3%80%8B.md)
   - [面经手册 · 第29篇《Spring IOC 特性有哪些，不会读不懂源码！》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-04-07-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC29%E7%AF%87%E3%80%8ASpring%20IOC%20%E7%89%B9%E6%80%A7%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%8C%E4%B8%8D%E4%BC%9A%E8%AF%BB%E4%B8%8D%E6%87%82%E6%BA%90%E7%A0%81%EF%BC%81%E3%80%8B.md)
   - [面经手册 · 第30篇《关于 Spring 中 getBean 的全流程源码解析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-04-18-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC30%E7%AF%87%E3%80%8A%E5%85%B3%E4%BA%8E%20Spring%20%E4%B8%AD%20getBean%20%E7%9A%84%E5%85%A8%E6%B5%81%E7%A8%8B%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%E3%80%8B.md)
   - [面经手册 · 第31篇《Spring Bean IOC、AOP 循环依赖解读》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/interview/2021-05-05-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E7%AC%AC31%E7%AF%87%E3%80%8ASpring%20Bean%20IOC%E3%80%81AOP%20%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96%E8%A7%A3%E8%AF%BB%E3%80%8B.md)
    
</details>

### 2.2 用Java实现JVM - 👉[**在线阅读**](https://bugstack.cn/md/java/develop-jvm/2019-05-01-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%80%E7%AB%A0%E3%80%8A%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E3%80%8B.html)

- [用Java实现JVM第一章《命令行工具》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-01-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%80%E7%AB%A0%E3%80%8A%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E3%80%8B.md)
- [用Java实现JVM第二章《搜索class文件》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-02-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%BA%8C%E7%AB%A0%E3%80%8A%E6%90%9C%E7%B4%A2class%E6%96%87%E4%BB%B6%E3%80%8B.md)
- [用Java实现JVM第三章《解析class文件》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-03-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%89%E7%AB%A0%E3%80%8A%E8%A7%A3%E6%9E%90class%E6%96%87%E4%BB%B6%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [用Java实现JVM第三章《解析class文件》附[classReader拆解]](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-04-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%89%E7%AB%A0%E3%80%8A%E8%A7%A3%E6%9E%90class%E6%96%87%E4%BB%B6%E3%80%8B%E9%99%84%5BclassReader%E6%8B%86%E8%A7%A3%5D.md)
- [用Java实现JVM第四章《运行时数据区》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-05-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E5%9B%9B%E7%AB%A0%E3%80%8A%E8%BF%90%E8%A1%8C%E6%97%B6%E6%95%B0%E6%8D%AE%E5%8C%BA%E3%80%8B.md)
- [用Java实现JVM第五章《指令集和解释器》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-06-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%BA%94%E7%AB%A0%E3%80%8A%E6%8C%87%E4%BB%A4%E9%9B%86%E5%92%8C%E8%A7%A3%E9%87%8A%E5%99%A8%E3%80%8B.md)
- [用Java实现JVM第六章《类和对象》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-07-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E5%85%AD%E7%AB%A0%E3%80%8A%E7%B1%BB%E5%92%8C%E5%AF%B9%E8%B1%A1%E3%80%8B.md)
- [用Java实现JVM第七章《方法调用和返回》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-08-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%83%E7%AB%A0%E3%80%8A%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%E5%92%8C%E8%BF%94%E5%9B%9E%E3%80%8B.md)
- [用Java实现JVM第八章《数组和字符串》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-09-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E5%85%AB%E7%AB%A0%E3%80%8A%E6%95%B0%E7%BB%84%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E3%80%8B.md)
- [用Java实现JVM第九章《本地方法调用》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-10-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B9%9D%E7%AB%A0%E3%80%8A%E6%9C%AC%E5%9C%B0%E6%96%B9%E6%B3%95%E8%B0%83%E7%94%A8%E3%80%8B.md)
- [用Java实现JVM第十章《异常处理》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/develop-jvm/2019-05-11-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E5%8D%81%E7%AB%A0%E3%80%8A%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E3%80%8B.md)

</details>

### 2.3 基础技术 - 👉[**在线阅读**](https://bugstack.cn/md/java/core/2020-01-06-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E5%92%8B%E5%98%9E%EF%BC%9F%E4%BD%A0%E7%9A%84IDEA%E8%BF%87%E6%9C%9F%E4%BA%86%E5%90%A7%EF%BC%81%E5%8A%A0%E4%B8%AAJar%E5%8C%85%E5%B0%B1%E7%A0%B4%E8%A7%A3%E4%BA%86%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.html)

- [有点干货-Jdk1.8新特性实战篇41个案例](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2019-12-10-%5B%E6%9C%89%E7%82%B9%E5%B9%B2%E8%B4%A7%5DJdk1.8%E6%96%B0%E7%89%B9%E6%80%A7%E5%AE%9E%E6%88%98%E7%AF%8741%E4%B8%AA%E6%A1%88%E4%BE%8B.md)
- [有点干货-JDK、CGLIB动态代理使用以及源码分析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2019-12-21-%5B%E6%9C%89%E7%82%B9%E5%B9%B2%E8%B4%A7%5DJDK%E3%80%81CGLIB%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E4%BD%BF%E7%94%A8%E4%BB%A5%E5%8F%8A%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90.md)
- [源码分析-咋嘞？你的IDEA过期了吧！加个Jar包就破解了，为什么？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2020-01-06-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E5%92%8B%E5%98%9E%EF%BC%9F%E4%BD%A0%E7%9A%84IDEA%E8%BF%87%E6%9C%9F%E4%BA%86%E5%90%A7%EF%BC%81%E5%8A%A0%E4%B8%AAJar%E5%8C%85%E5%B0%B1%E7%A0%B4%E8%A7%A3%E4%BA%86%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.md)

<details><summary><a>👉显示更多</a></summary></br>

- [似乎你总也记不住，byte的取值范围是 -127~128 还是 -128~127](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2020-01-18-%E4%BC%BC%E4%B9%8E%E4%BD%A0%E6%80%BB%E4%B9%9F%E8%AE%B0%E4%B8%8D%E4%BD%8F%EF%BC%8Cbyte%E7%9A%84%E5%8F%96%E5%80%BC%E8%8C%83%E5%9B%B4%E6%98%AF%20-127~128%20%E8%BF%98%E6%98%AF%20-128~127.md)
- [这种场景你还写ifelse你跟孩子坐一桌去吧](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2020-03-07-%E8%BF%99%E7%A7%8D%E5%9C%BA%E6%99%AF%E4%BD%A0%E8%BF%98%E5%86%99ifelse%E4%BD%A0%E8%B7%9F%E5%AD%A9%E5%AD%90%E5%9D%90%E4%B8%80%E6%A1%8C%E5%8E%BB%E5%90%A7.md)
- [汉字不能编程？别闹了，只是看着有点豪横！容易被开除！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2020-05-05-%E6%B1%89%E5%AD%97%E4%B8%8D%E8%83%BD%E7%BC%96%E7%A8%8B%EF%BC%9F%E5%88%AB%E9%97%B9%E4%BA%86%EF%BC%8C%E5%8F%AA%E6%98%AF%E7%9C%8B%E7%9D%80%E6%9C%89%E7%82%B9%E8%B1%AA%E6%A8%AA%EF%BC%81%E5%AE%B9%E6%98%93%E8%A2%AB%E5%BC%80%E9%99%A4%EF%BC%81.md)
- [鹿鼎记 · 韦小宝，丽春院、天地会、入皇宫等五个场景，搭配不同剧情讲解多线程和锁，真香！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2020-11-22-%E9%B9%BF%E9%BC%8E%E8%AE%B0%20%C2%B7%20%E9%9F%A6%E5%B0%8F%E5%AE%9D%EF%BC%8C%E4%B8%BD%E6%98%A5%E9%99%A2%E3%80%81%E5%A4%A9%E5%9C%B0%E4%BC%9A%E3%80%81%E5%85%A5%E7%9A%87%E5%AE%AB%E7%AD%89%E4%BA%94%E4%B8%AA%E5%9C%BA%E6%99%AF%EF%BC%8C%E6%90%AD%E9%85%8D%E4%B8%8D%E5%90%8C%E5%89%A7%E6%83%85%E8%AE%B2%E8%A7%A3%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%92%8C%E9%94%81%EF%BC%8C%E7%9C%9F%E9%A6%99%EF%BC%81.md)
- [一个Bug，让我发现了 Java 界的AJ锥！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/java/core/2021-04-21-%E4%B8%80%E4%B8%AABug%EF%BC%8C%E8%AE%A9%E6%88%91%E5%8F%91%E7%8E%B0%E4%BA%86%20Java%20%E7%95%8C%E7%9A%84AJ%E9%94%A5%EF%BC%81.md)

</details>

## 3. Spring

### 3.1 Spring 手撸专栏  - 👉[**在线阅读**](https://bugstack.cn/md/spring/develop-spring/2021-05-16-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Spring%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.html)

- 容器篇：IOC

   - [第1章：开篇介绍，手写Spring能给你带来什么？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-05-16-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Spring%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.md)
   - [第2章：小试牛刀，实现一个简单的Bean容器](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-05-20-%E7%AC%AC2%E7%AB%A0%EF%BC%9A%E5%B0%8F%E8%AF%95%E7%89%9B%E5%88%80%EF%BC%8C%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84Bean%E5%AE%B9%E5%99%A8.md)
   - [第3章：初显身手，运用设计模式，实现 Bean 的定义、注册、获取](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-05-23-%E7%AC%AC3%E7%AB%A0%EF%BC%9A%E5%88%9D%E6%98%BE%E8%BA%AB%E6%89%8B%EF%BC%8C%E8%BF%90%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%8C%E5%AE%9E%E7%8E%B0%20Bean%20%E7%9A%84%E5%AE%9A%E4%B9%89%E3%80%81%E6%B3%A8%E5%86%8C%E3%80%81%E8%8E%B7%E5%8F%96.md)
   - [第4章：崭露头角，基于Cglib实现含构造函数的类实例化策略](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-05-30-%E7%AC%AC4%E7%AB%A0%EF%BC%9A%E5%B4%AD%E9%9C%B2%E5%A4%B4%E8%A7%92%EF%BC%8C%E5%9F%BA%E4%BA%8ECglib%E5%AE%9E%E7%8E%B0%E5%90%AB%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%9A%84%E7%B1%BB%E5%AE%9E%E4%BE%8B%E5%8C%96%E7%AD%96%E7%95%A5.md)
   - [第5章：一鸣惊人，为Bean对象注入属性和依赖Bean的功能实现](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-02-%E7%AC%AC5%E7%AB%A0%EF%BC%9A%E4%B8%80%E9%B8%A3%E6%83%8A%E4%BA%BA%EF%BC%8C%E4%B8%BABean%E5%AF%B9%E8%B1%A1%E6%B3%A8%E5%85%A5%E5%B1%9E%E6%80%A7%E5%92%8C%E4%BE%9D%E8%B5%96Bean%E7%9A%84%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0.md)
   - [第6章：气吞山河，设计与实现资源加载器，从Spring.xml解析和注册Bean对象](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-09-%E7%AC%AC6%E7%AB%A0%EF%BC%9A%E6%B0%94%E5%90%9E%E5%B1%B1%E6%B2%B3%EF%BC%8C%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD%E5%99%A8%EF%BC%8C%E4%BB%8ESpring.xml%E8%A7%A3%E6%9E%90%E5%92%8C%E6%B3%A8%E5%86%8CBean%E5%AF%B9%E8%B1%A1.md)
   - [第7章：所向披靡，实现应用上下文，自动识别、资源加载、扩展机制](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-17-%E7%AC%AC7%E7%AB%A0%EF%BC%9A%E6%89%80%E5%90%91%E6%8A%AB%E9%9D%A1%EF%BC%8C%E5%AE%9E%E7%8E%B0%E5%BA%94%E7%94%A8%E4%B8%8A%E4%B8%8B%E6%96%87%EF%BC%8C%E8%87%AA%E5%8A%A8%E8%AF%86%E5%88%AB%E3%80%81%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD%E3%80%81%E6%89%A9%E5%B1%95%E6%9C%BA%E5%88%B6.md)
   - [第8章：龙行有风，向虚拟机注册钩子，实现Bean对象的初始化和销毁方法](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-23-%E7%AC%AC8%E7%AB%A0%EF%BC%9A%E9%BE%99%E8%A1%8C%E6%9C%89%E9%A3%8E%EF%BC%8C%E5%90%91%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%B3%A8%E5%86%8C%E9%92%A9%E5%AD%90%EF%BC%8C%E5%AE%9E%E7%8E%B0Bean%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E5%92%8C%E9%94%80%E6%AF%81%E6%96%B9%E6%B3%95.md)
   - [第9章：虎行有雨，定义标记类型Aware接口，实现感知容器对象](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-28-%E7%AC%AC9%E7%AB%A0%EF%BC%9A%E8%99%8E%E8%A1%8C%E6%9C%89%E9%9B%A8%EF%BC%8C%E5%AE%9A%E4%B9%89%E6%A0%87%E8%AE%B0%E7%B1%BB%E5%9E%8BAware%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%AE%9E%E7%8E%B0%E6%84%9F%E7%9F%A5%E5%AE%B9%E5%99%A8%E5%AF%B9%E8%B1%A1.md)
   - [第10章：横刀跃马，关于Bean对象作用域以及FactoryBean的实现和使用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-06-30-%E7%AC%AC10%E7%AB%A0%EF%BC%9A%E6%A8%AA%E5%88%80%E8%B7%83%E9%A9%AC%EF%BC%8C%E5%85%B3%E4%BA%8EBean%E5%AF%B9%E8%B1%A1%E4%BD%9C%E7%94%A8%E5%9F%9F%E4%BB%A5%E5%8F%8AFactoryBean%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%92%8C%E4%BD%BF%E7%94%A8.md)
   - [第11章：更上层楼，基于观察者实现，容器事件和事件监听器](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-07-07-%E7%AC%AC11%E7%AB%A0%EF%BC%9A%E6%9B%B4%E4%B8%8A%E5%B1%82%E6%A5%BC%EF%BC%8C%E5%9F%BA%E4%BA%8E%E8%A7%82%E5%AF%9F%E8%80%85%E5%AE%9E%E7%8E%B0%EF%BC%8C%E5%AE%B9%E5%99%A8%E4%BA%8B%E4%BB%B6%E5%92%8C%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC%E5%99%A8.md)

<details><summary><a>👉显示更多</a></summary></br>

- 代理篇：AOP

   - [第12章：炉火纯青，基于JDK和Cglib动态代理，实现AOP核心功能](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-07-13-%E7%AC%AC12%E7%AB%A0%EF%BC%9A%E7%82%89%E7%81%AB%E7%BA%AF%E9%9D%92%EF%BC%8C%E5%9F%BA%E4%BA%8EJDK%E5%92%8CCglib%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%EF%BC%8C%E5%AE%9E%E7%8E%B0AOP%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD.md)
   - [第13章：行云流水，把AOP动态代理，融入到Bean的生命周期](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-07-22-%E7%AC%AC13%E7%AB%A0%EF%BC%9A%E8%A1%8C%E4%BA%91%E6%B5%81%E6%B0%B4%EF%BC%8C%E6%8A%8AAOP%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%EF%BC%8C%E8%9E%8D%E5%85%A5%E5%88%B0Bean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.md)
   - [第14章：笑傲江湖，通过注解配置和包自动扫描的方式完成Bean对象的注册](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-07-27-%E7%AC%AC14%E7%AB%A0%EF%BC%9A%E7%AC%91%E5%82%B2%E6%B1%9F%E6%B9%96%EF%BC%8C%E9%80%9A%E8%BF%87%E6%B3%A8%E8%A7%A3%E9%85%8D%E7%BD%AE%E5%92%8C%E5%8C%85%E8%87%AA%E5%8A%A8%E6%89%AB%E6%8F%8F%E7%9A%84%E6%96%B9%E5%BC%8F%E5%AE%8C%E6%88%90Bean%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%B3%A8%E5%86%8C.md)
   - [第15章：万人之敌，通过注解给属性注入配置和Bean对象](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-08-03-%E7%AC%AC15%E7%AB%A0%EF%BC%9A%E4%B8%87%E4%BA%BA%E4%B9%8B%E6%95%8C%EF%BC%8C%E9%80%9A%E8%BF%87%E6%B3%A8%E8%A7%A3%E7%BB%99%E5%B1%9E%E6%80%A7%E6%B3%A8%E5%85%A5%E9%85%8D%E7%BD%AE%E5%92%8CBean%E5%AF%B9%E8%B1%A1.md)
   - [第16章：战无不胜，给代理对象的属性设置值](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-08-05-%E7%AC%AC16%E7%AB%A0%EF%BC%9A%E6%88%98%E6%97%A0%E4%B8%8D%E8%83%9C%EF%BC%8C%E7%BB%99%E4%BB%A3%E7%90%86%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%B1%9E%E6%80%A7%E8%AE%BE%E7%BD%AE%E5%80%BC.md)

- 高级篇：Design

   - [第17章：攻无不克，通过三级缓存解决循环依赖](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-08-07-%E7%AC%AC17%E7%AB%A0%EF%BC%9A%E6%94%BB%E6%97%A0%E4%B8%8D%E5%85%8B%EF%BC%8C%E9%80%9A%E8%BF%87%E4%B8%89%E7%BA%A7%E7%BC%93%E5%AD%98%E8%A7%A3%E5%86%B3%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96.md)
   - [第18章：挂印封刀，数据类型转换工厂设计实现](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-spring/2021-08-09-%E7%AC%AC18%E7%AB%A0%EF%BC%9A%E6%8C%82%E5%8D%B0%E5%B0%81%E5%88%80%EF%BC%8C%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E5%B7%A5%E5%8E%82%E8%AE%BE%E8%AE%A1%E5%AE%9E%E7%8E%B0.md)

</details>

### 3.2 Mybatis 手撸专栏  - 👉[**在线阅读**](https://bugstack.cn/md/spring/develop-mybatis/2022-03-20-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Mybatis%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.html)

- 介绍

    - [【难度☆☆☆☆☆】第01章：开篇介绍，我要带你撸 Mybatis 啦！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-03-20-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Mybatis%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.md)
    
- 第 1 部分 - 基础框架

    - [【难度★★☆☆☆】第02章：创建简单的映射器代理工厂](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-03-27-%E7%AC%AC2%E7%AB%A0%EF%BC%9A%E5%88%9B%E5%BB%BA%E7%AE%80%E5%8D%95%E7%9A%84%E6%98%A0%E5%B0%84%E5%99%A8%E4%BB%A3%E7%90%86%E5%B7%A5%E5%8E%82.md)
    - [【难度★★☆☆☆】第03章：实现映射器的注册和使用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-04-04-%E7%AC%AC3%E7%AB%A0%EF%BC%9A%E5%AE%9E%E7%8E%B0%E6%98%A0%E5%B0%84%E5%99%A8%E7%9A%84%E6%B3%A8%E5%86%8C%E5%92%8C%E4%BD%BF%E7%94%A8.md)
    - [【难度★★★☆☆】第04章：Mapper XML的解析和注册使用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-04-09-%E7%AC%AC4%E7%AB%A0%EF%BC%9AXML%E7%9A%84%E8%A7%A3%E6%9E%90%E5%92%8C%E6%B3%A8%E5%86%8C%E4%BD%BF%E7%94%A8.md)

- 第 2 部分 -  模块服务

    - [【难度★★★☆☆】第05章：数据源的解析、创建和使用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-04-09-%E7%AC%AC4%E7%AB%A0%EF%BC%9AXML%E7%9A%84%E8%A7%A3%E6%9E%90%E5%92%8C%E6%B3%A8%E5%86%8C%E4%BD%BF%E7%94%A8.md)
    - [【难度★★★★☆】第06章：数据源池化技术实现](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-04-17-%E7%AC%AC5%E7%AB%A0%EF%BC%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E7%9A%84%E8%A7%A3%E6%9E%90%E3%80%81%E5%88%9B%E5%BB%BA%E5%92%8C%E4%BD%BF%E7%94%A8.md)
    - [【难度★★★☆☆】第07章：SQL执行器的定义和实现](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-04-28-%E7%AC%AC7%E7%AB%A0%EF%BC%9ASQL%E6%89%A7%E8%A1%8C%E5%99%A8%E7%9A%84%E5%AE%9A%E4%B9%89%E5%92%8C%E5%AE%9E%E7%8E%B0.md)
    - [【难度★★★★★】第08章：把反射用到出神入化](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-05-03-%E7%AC%AC8%E7%AB%A0%EF%BC%9A%E6%8A%8A%E5%8F%8D%E5%B0%84%E7%94%A8%E5%88%B0%E5%87%BA%E7%A5%9E%E5%85%A5%E5%8C%96.md)

- 第 3 部分 -  串联流程

    - [【难度★★★★☆】第09章：细化XML语句构建器，完善静态SQL解析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-05-18-%E7%AC%AC9%E7%AB%A0%EF%BC%9A%E7%BB%86%E5%8C%96XML%E8%AF%AD%E5%8F%A5%E6%9E%84%E5%BB%BA%E5%99%A8%EF%BC%8C%E5%AE%8C%E5%96%84%E9%9D%99%E6%80%81SQL%E8%A7%A3%E6%9E%90.md)
    - [【难度★★★★☆】第10章：使用策略模式，调用参数处理器](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-05-26-%E7%AC%AC10%E7%AB%A0%EF%BC%9A%E4%BD%BF%E7%94%A8%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%EF%BC%8C%E8%B0%83%E7%94%A8%E5%8F%82%E6%95%B0%E5%A4%84%E7%90%86%E5%99%A8.md)
    - [【难度★★★☆☆】第11章：流程解耦，封装结果集处理器](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-06-02-%E7%AC%AC11%E7%AB%A0%EF%BC%9A%E6%B5%81%E7%A8%8B%E8%A7%A3%E8%80%A6%EF%BC%8C%E5%B0%81%E8%A3%85%E7%BB%93%E6%9E%9C%E9%9B%86%E5%A4%84%E7%90%86%E5%99%A8.md)
    - [【难度★★★☆☆】第12章：完善ORM框架，增删改查操作](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-06-10-%E7%AC%AC12%E7%AB%A0%EF%BC%9A%E5%AE%8C%E5%96%84ORM%E6%A1%86%E6%9E%B6%EF%BC%8C%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5%E6%93%8D%E4%BD%9C.md)


- 第 4 部分 -  扩展功能

    - [【难度★★★☆☆】第13章：通过注解配置执行SQL语句](https://articles.zsxq.com/id_cushlx5xx5wj.html)
    - [【难度★★★☆☆】第14章：解析和使用ResultMap映射参数配置](https://articles.zsxq.com/id_lszxhhridkrl.html)
    - [【难度★★★☆☆】第15章：返回Insert操作自增索引值](https://articles.zsxq.com/id_gwfa0x8nciwn.html)
    - [【难度★★★☆☆】第16章：解析含标签的动态SQL语句](https://articles.zsxq.com/id_1rzspttev8ls.html) 
    - [【难度★★★★☆】第17章：Plugin 插件扩展](https://articles.zsxq.com/id_k7havmcaefdk.html)
    - [【难度★★★★☆】第18章：一级缓存](https://articles.zsxq.com/id_8d0o471we1ig.html)
    - [【难度★★★★☆】第19章：二级缓存](https://articles.zsxq.com/id_gviwjzv5h4wp.html) 
    - [【难度★★★★☆】第20章：【作业】整合Spring](https://articles.zsxq.com/id_2pwtkmjixi73.html)
    
- 终章

    - [【番外】第21章：小册完结，一次源码深度学习旅行！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-07-06-%E7%AC%AC20%E7%AB%A0%EF%BC%9A%E6%95%B4%E5%90%88Spring.md)
    - [【番外】第22章：Mybatis 框架源码10种设计模式分析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/develop-mybatis/2022-07-15-%E7%AC%AC22%E7%AB%A0%EF%BC%9AMybatis%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md)

### 3.2 Spring Cloud - 👉[**在线阅读**](https://bugstack.cn/md/spring/spring-cloud/2019-10-31-Spring%20Cloud%E9%9B%B6%E3%80%8A%E6%80%BB%E6%9C%89%E4%B8%80%E5%81%8F%E6%A6%82%E8%BF%B0%E5%91%8A%E8%AF%89%E4%BD%A0SpringCloud%E6%98%AF%E4%BB%80%E4%B9%88%E3%80%8B.html)

- [Spring Cloud零《总有一偏概述告诉你SpringCloud是什么》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-10-31-Spring%20Cloud%E9%9B%B6%E3%80%8A%E6%80%BB%E6%9C%89%E4%B8%80%E5%81%8F%E6%A6%82%E8%BF%B0%E5%91%8A%E8%AF%89%E4%BD%A0SpringCloud%E6%98%AF%E4%BB%80%E4%B9%88%E3%80%8B.md)
- [Spring Cloud一《服务集群注册与发现 Eureka》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-01-Spring%20Cloud%E4%B8%80%E3%80%8A%E6%9C%8D%E5%8A%A1%E9%9B%86%E7%BE%A4%E6%B3%A8%E5%86%8C%E4%B8%8E%E5%8F%91%E7%8E%B0%20Eureka%E3%80%8B.md)
- [Spring Cloud二《服务提供与负载均衡调用 Eureka》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-02-Spring%20Cloud%E4%BA%8C%E3%80%8A%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E4%B8%8E%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E8%B0%83%E7%94%A8%20Eureka%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [Spring Cloud三《应用服务快速失败熔断降级保护 Hystrix》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-03-Spring%20Cloud%E4%B8%89%E3%80%8A%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%BF%AB%E9%80%9F%E5%A4%B1%E8%B4%A5%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7%E4%BF%9D%E6%8A%A4%20Hystrix%E3%80%8B.md)
- [Spring Cloud四《服务响应性能成功率监控 Hystrix》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-04-Spring%20Cloud%E5%9B%9B%E3%80%8A%E6%9C%8D%E5%8A%A1%E5%93%8D%E5%BA%94%E6%80%A7%E8%83%BD%E6%88%90%E5%8A%9F%E7%8E%87%E7%9B%91%E6%8E%A7%20Hystrix%E3%80%8B.md)
- [Spring Cloud五《Turbine 监控信息聚合展示 Hystrix》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-05-Spring%20Cloud%E4%BA%94%E3%80%8ATurbine%20%E7%9B%91%E6%8E%A7%E4%BF%A1%E6%81%AF%E8%81%9A%E5%90%88%E5%B1%95%E7%A4%BA%20Hystrix%E3%80%8B.md)
- [Spring Cloud六《基于Github Webhook动态刷新服务配置》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-06-Spring%20Cloud%E5%85%AD%E3%80%8A%E5%9F%BA%E4%BA%8EGithub%20Webhook%E5%8A%A8%E6%80%81%E5%88%B7%E6%96%B0%E6%9C%8D%E5%8A%A1%E9%85%8D%E7%BD%AE%E3%80%8B.md)
- [Spring Cloud七《基于RabbitMQ消息总线方式刷新配置服务》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-07-Spring%20Cloud%E4%B8%83%E3%80%8A%E5%9F%BA%E4%BA%8ERabbitMQ%E6%B6%88%E6%81%AF%E6%80%BB%E7%BA%BF%E6%96%B9%E5%BC%8F%E5%88%B7%E6%96%B0%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E3%80%8B.md)
- [Spring Cloud八《服务网关路由 Zuul1》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-08-Spring%20Cloud%E5%85%AB%E3%80%8A%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3%E8%B7%AF%E7%94%B1%20Zuul1%E3%80%8B.md)
- [Spring Cloud九《服务网关Zuul 动态路由与权限过滤器》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/spring-cloud/2019-11-24-Spring%20Cloud%E4%B9%9D%E3%80%8A%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3Zuul%20%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1%E4%B8%8E%E6%9D%83%E9%99%90%E8%BF%87%E6%BB%A4%E5%99%A8%E3%80%8B.md)

</details>

### 3.3 源码分析(Mybatis、Quartz) - 👉[**在线阅读**]()

- [Mybatis接口没有实现类为什么可以执行增删改查用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2019-12-25-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5DMybatis%E6%8E%A5%E5%8F%A3%E6%B2%A1%E6%9C%89%E5%AE%9E%E7%8E%B0%E7%B1%BB%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5.md)
- [Spring定时任务Quartz执行全过程源码解读用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2020-01-01-%5B%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%5DSpring%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1Quartz%E6%89%A7%E8%A1%8C%E5%85%A8%E8%BF%87%E7%A8%8B%E6%BA%90%E7%A0%81%E8%A7%A3%E8%AF%BB.md)
- [像盗墓一样分析Spring是怎么初始化xml并注册bean的用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2020-01-08-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E5%83%8F%E7%9B%97%E5%A2%93%E4%B8%80%E6%A0%B7%E5%88%86%E6%9E%90Spring%E6%98%AF%E6%80%8E%E4%B9%88%E5%88%9D%E5%A7%8B%E5%8C%96xml%E5%B9%B6%E6%B3%A8%E5%86%8Cbean%E7%9A%84.md)

<details><summary><a>👉显示更多</a></summary></br>

- [基于jdbc实现一个Demo版的Mybatis用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2020-01-13-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E5%9F%BA%E4%BA%8Ejdbc%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AADemo%E7%89%88%E7%9A%84Mybatis.md)
- [手写mybait-spring核心功能，干货好文一次学会工厂bean、类代理、bean注册的使用](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2020-01-20-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E6%89%8B%E5%86%99mybait-spring%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD%EF%BC%8C%E5%B9%B2%E8%B4%A7%E5%A5%BD%E6%96%87%E4%B8%80%E6%AC%A1%E5%AD%A6%E4%BC%9A%E5%B7%A5%E5%8E%82bean%E3%80%81%E7%B1%BB%E4%BB%A3%E7%90%86%E3%80%81bean%E6%B3%A8%E5%86%8C%E7%9A%84%E4%BD%BF%E7%94%A8.md)
- [为什么 insert 配置 "SELECT LAST_INSERT_ID()" 返回个0呢？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/spring/source-code/2022-06-24-%E4%B8%BA%E4%BB%80%E4%B9%88insert%E9%85%8D%E7%BD%AESELECT%20LAST_INSERT_ID()%E8%BF%94%E5%9B%9E%E4%B8%AA0%E5%91%A2.md)

</details>

## 4. 面向对象

### 4.1 设计模式 - 👉[**在线阅读**](https://bugstack.cn/md/develop/design-pattern/2020-05-20-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F%E3%80%8B.html)

- 介绍

    - [《重学Java设计模式》开始在B站录视频了！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2022-03-12-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8FB%E7%AB%99%E8%A7%86%E9%A2%91.md)

- 创建型模式

    - [重学 Java 设计模式《实战工厂方法模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-05-20-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《抽象工厂模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-05-24-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战建造者模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-05-26-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战原型模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-05-28-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战单例模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-05-31-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%E3%80%8B.md)    

<details><summary><a>👉显示更多</a></summary></br>

- 结构型模式

    - [重学 Java 设计模式《适配器模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-02-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战桥接模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-04-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战组合模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-08-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战装饰器模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-09-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战外观模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-11-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战享元模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-14-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战代理模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-16-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E3%80%8B.md)

- 行为型模式

    - [重学 Java 设计模式《实战责任链模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-18-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战命令模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-21-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战迭代器模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-23-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战中介者模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-27-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E4%B8%AD%E4%BB%8B%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战备忘录模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-28-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战观察者模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-06-30-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战状态模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-07-02-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战策略模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-07-05-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战模板模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-07-07-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E3%80%8B.md)
    - [重学 Java 设计模式《实战访问者模式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/design-pattern/2020-07-09-%E9%87%8D%E5%AD%A6%20Java%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E3%80%8B.md)

</details>

### 4.2 系统架构 - 👉[**在线阅读**](https://bugstack.cn/md/develop/framework/ddd/2019-10-15-DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%B8%80%E3%80%8A%E5%88%9D%E8%AF%86%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1DDD%E8%90%BD%E5%9C%B0%E3%80%8B.html)

- DDD 专题

    - [DDD专题案例一《初识领域驱动设计DDD落地》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/ddd/2019-10-15-DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%B8%80%E3%80%8A%E5%88%9D%E8%AF%86%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1DDD%E8%90%BD%E5%9C%B0%E3%80%8B.md)
    - [DDD专题案例二《领域层决策规则树服务设计》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/ddd/2019-10-16-DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%BA%8C%E3%80%8A%E9%A2%86%E5%9F%9F%E5%B1%82%E5%86%B3%E7%AD%96%E8%A7%84%E5%88%99%E6%A0%91%E6%9C%8D%E5%8A%A1%E8%AE%BE%E8%AE%A1%E3%80%8B.md)
    - [DDD专题案例三《领域驱动设计架构基于SpringCloud搭建微服务》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/ddd/2019-10-17-DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%B8%89%E3%80%8A%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E6%9E%B6%E6%9E%84%E5%9F%BA%E4%BA%8ESpringCloud%E6%90%AD%E5%BB%BA%E5%BE%AE%E6%9C%8D%E5%8A%A1%E3%80%8B.md)

- 工程框架

    - [架构框架搭建一《单体应用服务之SSM整合：Spring4 + SpringMvc + Mybatis》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/frame/2019-12-22-%E6%9E%B6%E6%9E%84%E6%A1%86%E6%9E%B6%E6%90%AD%E5%BB%BA%E4%B8%80%E3%80%8A%E5%8D%95%E4%BD%93%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E4%B9%8BSSM%E6%95%B4%E5%90%88%EF%BC%9ASpring4%20%2B%20SpringMvc%20%2B%20Mybatis%E3%80%8B.md)
    - [架构框架搭建二《Dubbo分布式领域驱动设计架构框体》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/frame/2019-12-31-%E6%9E%B6%E6%9E%84%E6%A1%86%E6%9E%B6%E6%90%AD%E5%BB%BA%E4%BA%8C%E3%80%8ADubbo%E5%88%86%E5%B8%83%E5%BC%8F%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1%E6%9E%B6%E6%9E%84%E6%A1%86%E4%BD%93%E3%80%8B.md)
  
<details><summary><a>👉显示更多</a></summary></br>  
    
- 架构方案

    - [基于IDEA插件开发和字节码插桩技术，实现研发交付质量自动分析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-02-04-%E5%9F%BA%E4%BA%8EIDEA%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%92%8C%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E6%8A%80%E6%9C%AF%EF%BC%8C%E5%AE%9E%E7%8E%B0%E7%A0%94%E5%8F%91%E4%BA%A4%E4%BB%98%E8%B4%A8%E9%87%8F%E8%87%AA%E5%8A%A8%E5%88%86%E6%9E%90.md)
    - [关于低代码编程的可持续性交付设计和分析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-02-21-%E5%85%B3%E4%BA%8E%E4%BD%8E%E4%BB%A3%E7%A0%81%E7%BC%96%E7%A8%8B%E7%9A%84%E5%8F%AF%E6%8C%81%E7%BB%AD%E6%80%A7%E4%BA%A4%E4%BB%98%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%88%86%E6%9E%90.md)
    - [工作两三年，整不明白架构图都画啥？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-02-28-%E5%B7%A5%E4%BD%9C%E4%B8%A4%E4%B8%89%E5%B9%B4%EF%BC%8C%E6%95%B4%E4%B8%8D%E6%98%8E%E7%99%BD%E6%9E%B6%E6%9E%84%E5%9B%BE%E9%83%BD%E7%94%BB%E5%95%A5%EF%BC%9F.md)
    - [笔记整理：技术架构涵盖内容和演变过程总结](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-03-04-%E7%AC%94%E8%AE%B0%E6%95%B4%E7%90%86%EF%BC%9A%E6%8A%80%E6%9C%AF%E6%9E%B6%E6%9E%84%E6%B6%B5%E7%9B%96%E5%86%85%E5%AE%B9%E5%92%8C%E6%BC%94%E5%8F%98%E8%BF%87%E7%A8%8B%E6%80%BB%E7%BB%93.md)
    - [不重复造轮子只是骗小孩子的，教你手撸 SpringBoot 脚手架！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-03-14-%E4%B8%8D%E9%87%8D%E5%A4%8D%E9%80%A0%E8%BD%AE%E5%AD%90%E5%8F%AA%E6%98%AF%E9%AA%97%E5%B0%8F%E5%AD%A9%E5%AD%90%E7%9A%84%EF%BC%8C%E6%95%99%E4%BD%A0%E6%89%8B%E6%92%B8%20SpringBoot%20%E8%84%9A%E6%89%8B%E6%9E%B6%EF%BC%81.md)
    - [刚火了的中台转头就拆，一大波公司放不下又拿不起来！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-03-24-%E5%88%9A%E7%81%AB%E4%BA%86%E7%9A%84%E4%B8%AD%E5%8F%B0%E8%BD%AC%E5%A4%B4%E5%B0%B1%E6%8B%86%EF%BC%8C%E4%B8%80%E5%A4%A7%E6%B3%A2%E5%85%AC%E5%8F%B8%E6%94%BE%E4%B8%8D%E4%B8%8B%E5%8F%88%E6%8B%BF%E4%B8%8D%E8%B5%B7%E6%9D%A5%EF%BC%81.md)
    - [调研字节码插桩技术，用于系统监控设计和实现](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2021-07-19-%E8%B0%83%E7%A0%94%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E6%8A%80%E6%9C%AF%EF%BC%8C%E7%94%A8%E4%BA%8E%E7%B3%BB%E7%BB%9F%E7%9B%91%E6%8E%A7%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%AE%9E%E7%8E%B0.md)
    - [基于库表分段扫描和数据Redis预热，优化分布式延迟任务触达时效性](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/framework/scheme/2022-02-14-%E5%9F%BA%E4%BA%8E%E5%BA%93%E8%A1%A8%E5%88%86%E6%AE%B5%E6%89%AB%E6%8F%8F%E5%92%8C%E6%95%B0%E6%8D%AERedis%E9%A2%84%E7%83%AD%EF%BC%8C%E4%BC%98%E5%8C%96%E5%88%86%E5%B8%83%E5%BC%8F%E5%BB%B6%E8%BF%9F%E4%BB%BB%E5%8A%A1%E8%A7%A6%E8%BE%BE%E6%97%B6%E6%95%88%E6%80%A7.md)
    - [怎么说服领导，能让我用DDD架构肝项目？](https://github.com/fuzhengwei/CodeGuide/blob/85f9a7e21065a5c3b2345f94734e903eb58d3b08/docs/md/develop/framework/scheme/2022-02-21-%E6%80%8E%E4%B9%88%E8%AF%B4%E6%9C%8D%E9%A2%86%E5%AF%BC%EF%BC%8C%E8%83%BD%E8%AE%A9%E6%88%91%E7%94%A8DDD%E6%9E%B6%E6%9E%84.md)

</details>

### 4.3 开发规范&事故 - 👉[**在线阅读**](https://bugstack.cn/md/develop/standard/2020-09-14-%E4%B8%80%E6%AC%A1%E4%BB%A3%E7%A0%81%E8%AF%84%E5%AE%A1%EF%BC%8C%E5%B7%AE%E7%82%B9%E8%BF%87%E4%B8%8D%E4%BA%86%E8%AF%95%E7%94%A8%E6%9C%9F%EF%BC%81.html)

- [握草，你竟然在代码里下毒！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2020-09-06-%E6%8F%A1%E8%8D%89%EF%BC%8C%E4%BD%A0%E7%AB%9F%E7%84%B6%E5%9C%A8%E4%BB%A3%E7%A0%81%E9%87%8C%E4%B8%8B%E6%AF%92%EF%BC%81.md)
- [一次代码评审，差点过不了试用期！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2020-09-14-%E4%B8%80%E6%AC%A1%E4%BB%A3%E7%A0%81%E8%AF%84%E5%AE%A1%EF%BC%8C%E5%B7%AE%E7%82%B9%E8%BF%87%E4%B8%8D%E4%BA%86%E8%AF%95%E7%94%A8%E6%9C%9F%EF%BC%81.md)
- [谁说明天上线，这货压根不知道开发流程！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2021-01-03-%E8%B0%81%E8%AF%B4%E6%98%8E%E5%A4%A9%E4%B8%8A%E7%BA%BF%EF%BC%8C%E8%BF%99%E8%B4%A7%E5%8E%8B%E6%A0%B9%E4%B8%8D%E7%9F%A5%E9%81%93%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B%EF%BC%81.md)
- [握草，这些研发事故30%我都干过！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2021-01-10-%E6%8F%A1%E8%8D%89%EF%BC%8C%E8%BF%99%E4%BA%9B%E7%A0%94%E5%8F%91%E4%BA%8B%E6%95%8530%25%E6%88%91%E9%83%BD%E5%B9%B2%E8%BF%87%EF%BC%81.md)

<details><summary><a>👉显示更多</a></summary></br>

- [还重构？就你那代码只能铲了重写！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2021-09-15-%E8%BF%98%E9%87%8D%E6%9E%84%EF%BC%9F%E5%B0%B1%E4%BD%A0%E9%82%A3%E4%BB%A3%E7%A0%81%E5%8F%AA%E8%83%BD%E9%93%B2%E4%BA%86%E9%87%8D%E5%86%99%EF%BC%81.md)
- [p3c 插件，是怎么检查出你那屎山的代码？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2021-09-27-p3c%20%E6%8F%92%E4%BB%B6%EF%BC%8C%E6%98%AF%E6%80%8E%E4%B9%88%E6%A3%80%E6%9F%A5%E5%87%BA%E4%BD%A0%E9%82%A3%E5%B1%8E%E5%B1%B1%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%9F.md)
- [12种 vo2dto 方法，就 BeanUtils.copyProperties 压测最拉胯](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2021-10-10-12%E7%A7%8D%20vo2dto%20%E6%96%B9%E6%B3%95%EF%BC%8C%E5%B0%B1%20BeanUtils.copyProperties%20%E5%8E%8B%E6%B5%8B%E6%9C%80%E6%8B%89%E8%83%AF.md)
- [架构师深夜把玩 ApiPost，分享细腻的体验！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2022-03-06-ApiPost.md)
- [你说写代码，最常用的3个设计模式是啥？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/develop/standard/2022-05-15-%E4%BD%A0%E8%AF%B4%E5%86%99%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%9C%80%E5%B8%B8%E7%94%A8%E7%9A%843%E4%B8%AA%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%98%AF%E5%95%A5%EF%BC%9F.md)

</details>

## 5. 中间件

### 5.1 SpringBoot 中间件开发 - 👉[**在线阅读**](https://bugstack.cn/md/assembly/middleware/2019-12-02-SpringBoot%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%E4%B8%AD%E9%97%B4%E4%BB%B6%E4%B9%8B%E7%BB%9F%E4%B8%80%E7%99%BD%E5%90%8D%E5%8D%95%E9%AA%8C%E8%AF%81.html)

- [SpringBoot服务治理中间件之统一白名单验证](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/assembly/middleware/2019-12-02-SpringBoot%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%E4%B8%AD%E9%97%B4%E4%BB%B6%E4%B9%8B%E7%BB%9F%E4%B8%80%E7%99%BD%E5%90%8D%E5%8D%95%E9%AA%8C%E8%AF%81.md)
- [发布Jar包到Maven中央仓库，为开发开源中间件做准备](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/assembly/middleware/2019-12-07-%E5%8F%91%E5%B8%83Jar%E5%8C%85%E5%88%B0Maven%E4%B8%AD%E5%A4%AE%E4%BB%93%E5%BA%93%EF%BC%8C%E4%B8%BA%E5%BC%80%E5%8F%91%E5%BC%80%E6%BA%90%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%81%9A%E5%87%86%E5%A4%87.md)
- [开发基于SpringBoot的分布式任务中间件DcsSchedule](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/assembly/middleware/2019-12-08-%E5%BC%80%E5%8F%91%E5%9F%BA%E4%BA%8ESpringBoot%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E4%B8%AD%E9%97%B4%E4%BB%B6DcsSchedule.md)

<details><summary><a>👉显示更多</a></summary></br>

- [基于Hash散列，数据库路由组件设计](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/assembly/middleware/2021-08-19-%E5%9F%BA%E4%BA%8EHash%E6%95%A3%E5%88%97%EF%BC%8C%E6%95%B0%E6%8D%AE%E5%BA%93%E8%B7%AF%E7%94%B1%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1.md)

</details>

### 5.2 IDEA-Plugin - 👉[**在线阅读**](https://bugstack.cn/md/assembly/idea-plugin/2021-08-27-%E6%8A%80%E6%9C%AF%E8%B0%83%E7%A0%94%EF%BC%8CIDEA%20%E6%8F%92%E4%BB%B6%E6%80%8E%E4%B9%88%E5%BC%80%E5%8F%91%EF%BC%9F.html)

- 第1章：开发入门

    - [第1节：IDEA 插件怎么开发](https://bugstack.cn/md/assembly/idea-plugin/2021-08-27-%E6%8A%80%E6%9C%AF%E8%B0%83%E7%A0%94%EF%BC%8CIDEA%20%E6%8F%92%E4%BB%B6%E6%80%8E%E4%B9%88%E5%BC%80%E5%8F%91%EF%BC%9F.html)
    - [第2节：IDEA 插件怎么发布](https://bugstack.cn/md/assembly/idea-plugin/2021-08-29-%E6%8A%80%E6%9C%AF%E5%AE%9E%E8%B7%B5%EF%BC%8CIDEA%20%E6%8F%92%E4%BB%B6%E6%80%8E%E4%B9%88%E5%8F%91%E5%B8%83%EF%BC%9F.html)

- 第2章：基础功能

    - [第3节：两种方式创建插件工程](https://bugstack.cn/md/assembly/idea-plugin/2021-10-18-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E4%B8%80%E8%8A%82%EF%BC%9A%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F%E5%88%9B%E5%BB%BA%E6%8F%92%E4%BB%B6%E5%B7%A5%E7%A8%8B.html)
    - [第4节：配置窗体和侧边栏窗体的使用](https://bugstack.cn/md/assembly/idea-plugin/2021-11-03-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E4%BA%8C%E8%8A%82%EF%BC%9A%E9%85%8D%E7%BD%AE%E7%AA%97%E4%BD%93%E5%92%8C%E4%BE%A7%E8%BE%B9%E6%A0%8F%E7%AA%97%E4%BD%93%E7%9A%84%E4%BD%BF%E7%94%A8.html)
    - [第5节：开发工具栏和Tab页，展示股票行情和K线](https://bugstack.cn/md/assembly/idea-plugin/2021-11-18-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E4%B8%89%E8%8A%82%EF%BC%9A%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%E6%A0%8F%E5%92%8CTab%E9%A1%B5%EF%BC%8C%E5%B1%95%E7%A4%BA%E8%82%A1%E7%A5%A8%E8%A1%8C%E6%83%85%E5%92%8CK%E7%BA%BF.html)

- 第3章：基建设计

    - [第6节：扩展创建工程向导步骤，开发DDD脚手架](https://bugstack.cn/md/assembly/idea-plugin/2021-11-24-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E5%9B%9B%E8%8A%82%EF%BC%9A%E6%89%A9%E5%B1%95%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B%E5%90%91%E5%AF%BC%E6%AD%A5%E9%AA%A4%EF%BC%8C%E5%BC%80%E5%8F%91DDD%E8%84%9A%E6%89%8B%E6%9E%B6.html)
    - [第7节：IDEA工程右键菜单，自动生成ORM代码](https://bugstack.cn/md/assembly/idea-plugin/2021-12-08-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E4%BA%94%E8%8A%82%EF%BC%9AIDEA%E5%B7%A5%E7%A8%8B%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%EF%BC%8C%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90ORM%E4%BB%A3%E7%A0%81.html)
    - [第8节：选定对象批量织入“x.set(y.get)”代码，自动生成vo2dto](https://bugstack.cn/md/assembly/idea-plugin/2021-12-14-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC%E5%85%AD%E8%8A%82%EF%BC%9A%E4%BB%A5%E7%BB%87%E5%85%A5%E4%BB%A3%E7%A0%81%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E8%87%AA%E5%8A%A8%E5%A4%84%E7%90%86vo2dto.html)

- 第4章：辅助工具
    
    - [第9节：通过Inspection机制，对静态代码安全审查](https://bugstack.cn/md/assembly/idea-plugin/2021-12-22-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC7%E8%8A%82%EF%BC%9A%E9%80%9A%E8%BF%87Inspection%E6%9C%BA%E5%88%B6%EF%BC%8C%E4%B8%BA%E9%9D%99%E6%80%81%E4%BB%A3%E7%A0%81%E5%AE%89%E5%85%A8%E5%AE%A1%E6%9F%A5.html)
    - [第10节：在插件中引入探针，基于字节码插桩获取执行SQL](https://bugstack.cn/md/assembly/idea-plugin/2022-01-17-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC8%E8%8A%82%EF%BC%9A%E5%9C%A8%E6%8F%92%E4%BB%B6%E4%B8%AD%E5%BC%95%E5%85%A5%E6%8E%A2%E9%92%88%EF%BC%8C%E5%9F%BA%E4%BA%8E%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E8%8E%B7%E5%8F%96%E6%89%A7%E8%A1%8CSQL.html)
    - [第11节：基于IDEA插件开发和字节码插桩技术，实现研发交付质量自动分析](https://bugstack.cn/md/assembly/idea-plugin/2022-01-23-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC10%E8%8A%82%EF%BC%9A%E5%9F%BA%E4%BA%8E%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E9%87%87%E9%9B%86%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81%E4%BA%A4%E4%BB%98%E8%B4%A8%E9%87%8F%E8%87%AA%E5%8A%A8%E5%88%86%E6%9E%90.html)
    - [第12节：加载文件生成链表单词树，输入属性时英文校准提醒](https://bugstack.cn/md/assembly/idea-plugin/2022-01-22-%E3%80%8AIntelliJ%20IDEA%20%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E3%80%8B%E7%AC%AC9%E8%8A%82%EF%BC%9A%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6%E7%94%9F%E6%88%90%E9%93%BE%E8%A1%A8%E5%8D%95%E8%AF%8D%E6%A0%91%EF%BC%8C%E8%BE%93%E5%85%A5%E5%B1%9E%E6%80%A7%E6%97%B6%E8%8B%B1%E6%96%87%E6%A0%A1%E5%87%86%E6%8F%90%E9%86%92.html)

## 6. Netty 4.x 

### 6.1 基础入门篇 - 👉[**在线阅读**](https://bugstack.cn/md/netty/base/2019-07-30-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E9%9B%B6%E3%80%8A%E5%88%9D%E5%85%A5JavaIO%E4%B9%8B%E9%97%A8BIO%E3%80%81NIO%E3%80%81AIO%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0%E3%80%8B.html)

- [netty案例，netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-07-30-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E9%9B%B6%E3%80%8A%E5%88%9D%E5%85%A5JavaIO%E4%B9%8B%E9%97%A8BIO%E3%80%81NIO%E3%80%81AIO%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇一《嗨！NettyServer》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-01-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%B8%80%E3%80%8A%E5%97%A8%EF%BC%81NettyServer%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇二《NettyServer接收数据》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-05-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%BA%8C%E3%80%8ANettyServer%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [netty案例，netty4.1基础入门篇三《NettyServer字符串解码器》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-06-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%B8%89%E3%80%8ANettyServer%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%A7%A3%E7%A0%81%E5%99%A8%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇四《NettyServer收发数据》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-07-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%9B%9B%E3%80%8ANettyServer%E6%94%B6%E5%8F%91%E6%95%B0%E6%8D%AE%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇五《NettyServer字符串编码器》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-08-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%BA%94%E3%80%8ANettyServer%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%BC%96%E7%A0%81%E5%99%A8%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇六《NettyServer群发消息》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-09-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%85%AD%E3%80%8ANettyServer%E7%BE%A4%E5%8F%91%E6%B6%88%E6%81%AF%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇七《嗨！NettyClient》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-10-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%B8%83%E3%80%8A%E5%97%A8%EF%BC%81NettyClient%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇八《NettyClient半包粘包处理、编码解码处理、收发数据方式》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-11-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%85%AB%E3%80%8ANettyClient%E5%8D%8A%E5%8C%85%E7%B2%98%E5%8C%85%E5%A4%84%E7%90%86%E3%80%81%E7%BC%96%E7%A0%81%E8%A7%A3%E7%A0%81%E5%A4%84%E7%90%86%E3%80%81%E6%94%B6%E5%8F%91%E6%95%B0%E6%8D%AE%E6%96%B9%E5%BC%8F%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇九《自定义编码解码器，处理半包、粘包数据》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-12-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E4%B9%9D%E3%80%8A%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BC%96%E7%A0%81%E8%A7%A3%E7%A0%81%E5%99%A8%EF%BC%8C%E5%A4%84%E7%90%86%E5%8D%8A%E5%8C%85%E3%80%81%E7%B2%98%E5%8C%85%E6%95%B0%E6%8D%AE%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇十《关于ChannelOutboundHandlerAdapter简单使用》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-13-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%8D%81%E3%80%8A%E5%85%B3%E4%BA%8EChannelOutboundHandlerAdapter%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇十一《netty udp通信方式案例Demo》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-14-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%8D%81%E4%B8%80%E3%80%8Anetty%20udp%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F%E6%A1%88%E4%BE%8BDemo%E3%80%8B.md)
- [netty案例，netty4.1基础入门篇十二《简单实现一个基于Netty搭建的Http服务》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/base/2019-08-15-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E5%8D%81%E4%BA%8C%E3%80%8A%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E5%9F%BA%E4%BA%8ENetty%E6%90%AD%E5%BB%BA%E7%9A%84Http%E6%9C%8D%E5%8A%A1%E3%80%8B.md)

</details>

### 6.2 中级拓展篇 - 👉[**在线阅读**](https://bugstack.cn/md/netty/expand/2019-08-16-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%B8%80%E3%80%8ANetty%E4%B8%8ESpringBoot%E6%95%B4%E5%90%88%E3%80%8B.html)

- [netty案例，netty4.1中级拓展篇一《Netty与SpringBoot整合》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-16-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%B8%80%E3%80%8ANetty%E4%B8%8ESpringBoot%E6%95%B4%E5%90%88%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇二《Netty使用Protobuf传输数据》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-17-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%BA%8C%E3%80%8ANetty%E4%BD%BF%E7%94%A8Protobuf%E4%BC%A0%E8%BE%93%E6%95%B0%E6%8D%AE%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇三《Netty传输Java对象》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-18-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%B8%89%E3%80%8ANetty%E4%BC%A0%E8%BE%93Java%E5%AF%B9%E8%B1%A1%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [netty案例，netty4.1中级拓展篇四《Netty传输文件、分片发送、断点续传》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-19-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%9B%9B%E3%80%8ANetty%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6%E3%80%81%E5%88%86%E7%89%87%E5%8F%91%E9%80%81%E3%80%81%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇五《基于Netty搭建WebSocket，模仿微信聊天页面》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-20-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%BA%94%E3%80%8A%E5%9F%BA%E4%BA%8ENetty%E6%90%AD%E5%BB%BAWebSocket%EF%BC%8C%E6%A8%A1%E4%BB%BF%E5%BE%AE%E4%BF%A1%E8%81%8A%E5%A4%A9%E9%A1%B5%E9%9D%A2%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇六《SpringBoot+Netty+Elasticsearch收集日志信息数据存储》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-21-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%85%AD%E3%80%8ASpringBoot%2BNetty%2BElasticsearch%E6%94%B6%E9%9B%86%E6%97%A5%E5%BF%97%E4%BF%A1%E6%81%AF%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇七《Netty请求响应同步通信》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-22-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%B8%83%E3%80%8ANetty%E8%AF%B7%E6%B1%82%E5%93%8D%E5%BA%94%E5%90%8C%E6%AD%A5%E9%80%9A%E4%BF%A1%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇八《Netty心跳服务与断线重连》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-23-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%85%AB%E3%80%8ANetty%E5%BF%83%E8%B7%B3%E6%9C%8D%E5%8A%A1%E4%B8%8E%E6%96%AD%E7%BA%BF%E9%87%8D%E8%BF%9E%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇九《Netty集群部署实现跨服务端通信的落地方案》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-24-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E4%B9%9D%E3%80%8ANetty%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2%E5%AE%9E%E7%8E%B0%E8%B7%A8%E6%9C%8D%E5%8A%A1%E7%AB%AF%E9%80%9A%E4%BF%A1%E7%9A%84%E8%90%BD%E5%9C%B0%E6%96%B9%E6%A1%88%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇十《Netty接收发送多种协议消息类型的通信处理方案》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-25-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%8D%81%E3%80%8ANetty%E6%8E%A5%E6%94%B6%E5%8F%91%E9%80%81%E5%A4%9A%E7%A7%8D%E5%8D%8F%E8%AE%AE%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%80%9A%E4%BF%A1%E5%A4%84%E7%90%86%E6%96%B9%E6%A1%88%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇十一《Netty基于ChunkedStream数据流切块传输》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-26-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%8D%81%E4%B8%80%E3%80%8ANetty%E5%9F%BA%E4%BA%8EChunkedStream%E6%95%B0%E6%8D%AE%E6%B5%81%E5%88%87%E5%9D%97%E4%BC%A0%E8%BE%93%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇十二《Netty流量整形数据流速率控制分析与实战》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-27-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%8D%81%E4%BA%8C%E3%80%8ANetty%E6%B5%81%E9%87%8F%E6%95%B4%E5%BD%A2%E6%95%B0%E6%8D%AE%E6%B5%81%E9%80%9F%E7%8E%87%E6%8E%A7%E5%88%B6%E5%88%86%E6%9E%90%E4%B8%8E%E5%AE%9E%E6%88%98%E3%80%8B.md)
- [netty案例，netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/expand/2019-08-28-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E4%B8%AD%E7%BA%A7%E6%8B%93%E5%B1%95%E7%AF%87%E5%8D%81%E4%B8%89%E3%80%8ANetty%E5%9F%BA%E4%BA%8ESSL%E5%AE%9E%E7%8E%B0%E4%BF%A1%E6%81%AF%E4%BC%A0%E8%BE%93%E8%BF%87%E7%A8%8B%E4%B8%AD%E5%8F%8C%E5%90%91%E5%8A%A0%E5%AF%86%E9%AA%8C%E8%AF%81%E3%80%8B.md)

</details>

### 6.3 高级应用篇 - 👉[**在线阅读**](https://bugstack.cn/md/netty/application/2019-09-01-%E6%89%8B%E5%86%99RPC%E6%A1%86%E6%9E%B6%E7%AC%AC%E4%B8%80%E7%AB%A0%E3%80%8A%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AExml%E3%80%8B.html)

- [手写RPC框架第一章《自定义配置xml》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/application/2019-09-01-%E6%89%8B%E5%86%99RPC%E6%A1%86%E6%9E%B6%E7%AC%AC%E4%B8%80%E7%AB%A0%E3%80%8A%E8%87%AA%E5%AE%9A%E4%B9%89%E9%85%8D%E7%BD%AExml%E3%80%8B.md)
- [手写RPC框架第二章《netty通信》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/application/2019-09-02-%E6%89%8B%E5%86%99RPC%E6%A1%86%E6%9E%B6%E7%AC%AC%E4%BA%8C%E7%AB%A0%E3%80%8Anetty%E9%80%9A%E4%BF%A1%E3%80%8B.md)
- [手写RPC框架第三章《RPC中间件》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/application/2019-09-03-%E6%89%8B%E5%86%99RPC%E6%A1%86%E6%9E%B6%E7%AC%AC%E4%B8%89%E7%AB%A0%E3%80%8ARPC%E4%B8%AD%E9%97%B4%E4%BB%B6%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [websocket与下位机通过netty方式通信传输行为信息](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/application/2019-12-01-websocket%E4%B8%8E%E4%B8%8B%E4%BD%8D%E6%9C%BA%E9%80%9A%E8%BF%87netty%E6%96%B9%E5%BC%8F%E9%80%9A%E4%BF%A1%E4%BC%A0%E8%BE%93%E8%A1%8C%E4%B8%BA%E4%BF%A1%E6%81%AF.md)
- [给学习加点实践，开发一个分布式IM即时通信系统](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/application/2021-08-17-%E7%BB%99%E5%AD%A6%E4%B9%A0%E5%8A%A0%E7%82%B9%E5%AE%9E%E8%B7%B5%EF%BC%8C%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E5%88%86%E5%B8%83%E5%BC%8FIM%E5%8D%B3%E6%97%B6%E9%80%9A%E4%BF%A1%E7%B3%BB%E7%BB%9F.md)

</details>

### 6.4 源码分析篇 - 👉[**在线阅读**](https://bugstack.cn/md/netty/source-code/2019-09-10-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E4%B8%80%E3%80%8ANioEventLoopGroup%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E3%80%8B.html)

- [netty案例，netty4.1源码分析篇一《NioEventLoopGroup源码分析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-10-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E4%B8%80%E3%80%8ANioEventLoopGroup%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E3%80%8B.md)
- [netty案例，netty4.1源码分析篇二《ServerBootstrap配置与绑定启动》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-11-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E4%BA%8C%E3%80%8AServerBootstrap%E9%85%8D%E7%BD%AE%E4%B8%8E%E7%BB%91%E5%AE%9A%E5%90%AF%E5%8A%A8%E3%80%8B.md)
- [netty案例，netty4.1源码分析篇三《Netty服务端初始化过程以及反射工厂的作用》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-12-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E4%B8%89%E3%80%8ANetty%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%88%9D%E5%A7%8B%E5%8C%96%E8%BF%87%E7%A8%8B%E4%BB%A5%E5%8F%8A%E5%8F%8D%E5%B0%84%E5%B7%A5%E5%8E%82%E7%9A%84%E4%BD%9C%E7%94%A8%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [netty案例，netty4.1源码分析篇四《ByteBuf的数据结构在使用方式中的剖析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-13-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E5%9B%9B%E3%80%8AByteBuf%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%9C%A8%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F%E4%B8%AD%E7%9A%84%E5%89%96%E6%9E%90%E3%80%8B.md)
- [netty案例，netty4.1源码分析篇五《一行简单的writeAndFlush都做了哪些事》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-14-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E4%BA%94%E3%80%8A%E4%B8%80%E8%A1%8C%E7%AE%80%E5%8D%95%E7%9A%84writeAndFlush%E9%83%BD%E5%81%9A%E4%BA%86%E5%93%AA%E4%BA%9B%E4%BA%8B%E3%80%8B.md)
- [netty案例，netty4.1源码分析篇六《Netty异步架构监听类Promise源码分析》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/netty/source-code/2019-09-15-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E7%AF%87%E5%85%AD%E3%80%8ANetty%E5%BC%82%E6%AD%A5%E6%9E%B6%E6%9E%84%E7%9B%91%E5%90%AC%E7%B1%BBPromise%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E3%80%8B.md)

</details>

## 7. 字节码编程

### 7.1 框架 - 👉[**在线阅读**](https://bugstack.cn/md/bytecode/asm/2020-03-25-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5D%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%8F%AA%E5%86%99CRUD%EF%BC%8C%E9%82%A3%E8%BF%99%E7%A7%8D%E6%8A%80%E6%9C%AF%E4%BD%A0%E6%B0%B8%E8%BF%9C%E7%A2%B0%E4%B8%8D%E5%88%B0.html)

**ASM**

- [如果你只写CRUD，那这种技术你永远碰不到](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm/2020-03-25-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5D%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%8F%AA%E5%86%99CRUD%EF%BC%8C%E9%82%A3%E8%BF%99%E7%A7%8D%E6%8A%80%E6%9C%AF%E4%BD%A0%E6%B0%B8%E8%BF%9C%E7%A2%B0%E4%B8%8D%E5%88%B0.md)
- [JavaAgent+ASM字节码插桩采集方法名称以及入参和出参结果并记录方法耗时](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm/2020-04-05-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5DJavaAgent%2BASM%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E9%87%87%E9%9B%86%E6%96%B9%E6%B3%95%E5%90%8D%E7%A7%B0%E4%BB%A5%E5%8F%8A%E5%85%A5%E5%8F%82%E5%92%8C%E5%87%BA%E5%8F%82%E7%BB%93%E6%9E%9C%E5%B9%B6%E8%AE%B0%E5%BD%95%E6%96%B9%E6%B3%95%E8%80%97%E6%97%B6.md)
- [用字节码增强技术给所有方法加上TryCatch捕获异常并输出](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm/2020-04-16-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5D%E7%94%A8%E5%AD%97%E8%8A%82%E7%A0%81%E5%A2%9E%E5%BC%BA%E6%8A%80%E6%9C%AF%E7%BB%99%E6%89%80%E6%9C%89%E6%96%B9%E6%B3%95%E5%8A%A0%E4%B8%8ATryCatch%E6%8D%95%E8%8E%B7%E5%BC%82%E5%B8%B8%E5%B9%B6%E8%BE%93%E5%87%BA.md)

<details><summary><a>👉显示更多</a></summary></br>

**Javassist**

- [Javassist篇一《基于javassist的第一个案例helloworld》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/javassist/2020-04-19-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CJavassist%E7%AF%87%E4%B8%80%E3%80%8A%E5%9F%BA%E4%BA%8Ejavassist%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%A1%88%E4%BE%8Bhelloworld%E3%80%8B.md)
- [Javassist篇二《定义属性以及创建方法时多种入参和出参类型的使用》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/javassist/2020-04-20-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CJavassist%E7%AF%87%E4%BA%8C%E3%80%8A%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E4%BB%A5%E5%8F%8A%E5%88%9B%E5%BB%BA%E6%96%B9%E6%B3%95%E6%97%B6%E5%A4%9A%E7%A7%8D%E5%85%A5%E5%8F%82%E5%92%8C%E5%87%BA%E5%8F%82%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E3%80%8B.md)
- [Javassist篇三《使用Javassist在运行时重新加载类「替换原方法输出不一样的结果」》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/javassist/2020-04-21-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CJavassist%E7%AF%87%E4%B8%89%E3%80%8A%E4%BD%BF%E7%94%A8Javassist%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E9%87%8D%E6%96%B0%E5%8A%A0%E8%BD%BD%E7%B1%BB%E3%80%8C%E6%9B%BF%E6%8D%A2%E5%8E%9F%E6%96%B9%E6%B3%95%E8%BE%93%E5%87%BA%E4%B8%8D%E4%B8%80%E6%A0%B7%E7%9A%84%E7%BB%93%E6%9E%9C%E3%80%8D%E3%80%8B.md)
- [Javassist篇四《通过字节码插桩监控方法采集运行时入参出参和异常信息》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/javassist/2020-04-27-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CJavassist%E7%AF%87%E5%9B%9B%E3%80%8A%E9%80%9A%E8%BF%87%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E7%9B%91%E6%8E%A7%E6%96%B9%E6%B3%95%E9%87%87%E9%9B%86%E8%BF%90%E8%A1%8C%E6%97%B6%E5%85%A5%E5%8F%82%E5%87%BA%E5%8F%82%E5%92%8C%E5%BC%82%E5%B8%B8%E4%BF%A1%E6%81%AF%E3%80%8B.md)
- [Javassist篇五《使用Bytecode指令码生成含有自定义注解的类和方法》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/javassist/2020-04-29-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CJavassist%E7%AF%87%E4%BA%94%E3%80%8A%E4%BD%BF%E7%94%A8Bytecode%E6%8C%87%E4%BB%A4%E7%A0%81%E7%94%9F%E6%88%90%E5%90%AB%E6%9C%89%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B3%A8%E8%A7%A3%E7%9A%84%E7%B1%BB%E5%92%8C%E6%96%B9%E6%B3%95%E3%80%8B.md)

**Byte-Buddy**

- [Byte-buddy篇一《基于Byte Buddy语法创建的第一个HelloWorld》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/byte-buddy/2020-05-08-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CByte-buddy%E7%AF%87%E4%B8%80%E3%80%8A%E5%9F%BA%E4%BA%8EByte%20Buddy%E8%AF%AD%E6%B3%95%E5%88%9B%E5%BB%BA%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AAHelloWorld%E3%80%8B.md)
- [Byte-buddy篇二《监控方法执行耗时动态获取出入参类型和值》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/byte-buddy/2020-05-12-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CByte-buddy%E7%AF%87%E4%BA%8C%E3%80%8A%E7%9B%91%E6%8E%A7%E6%96%B9%E6%B3%95%E6%89%A7%E8%A1%8C%E8%80%97%E6%97%B6%E5%8A%A8%E6%80%81%E8%8E%B7%E5%8F%96%E5%87%BA%E5%85%A5%E5%8F%82%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%80%BC%E3%80%8B.md)
- [Byte-buddy篇三《使用委托实现抽象类方法并注入自定义注解信息》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/byte-buddy/2020-05-14-%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%EF%BC%8CByte-buddy%E7%AF%87%E4%B8%89%E3%80%8A%E4%BD%BF%E7%94%A8%E5%A7%94%E6%89%98%E5%AE%9E%E7%8E%B0%E6%8A%BD%E8%B1%A1%E7%B1%BB%E6%96%B9%E6%B3%95%E5%B9%B6%E6%B3%A8%E5%85%A5%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B3%A8%E8%A7%A3%E4%BF%A1%E6%81%AF%E3%80%8B.md)

</details>

### 7.2 全链路监控 - 👉[**在线阅读**](https://bugstack.cn/md/bytecode/agent/2019-07-10-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E4%B8%80%E3%80%8A%E5%97%A8%EF%BC%81JavaAgent%E3%80%8B.html)

- [基于JavaAgent的全链路监控一《嗨！JavaAgent》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-10-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E4%B8%80%E3%80%8A%E5%97%A8%EF%BC%81JavaAgent%E3%80%8B.md)
- [基于JavaAgent的全链路监控二《通过字节码增加监控执行耗时》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-11-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E4%BA%8C%E3%80%8A%E9%80%9A%E8%BF%87%E5%AD%97%E8%8A%82%E7%A0%81%E5%A2%9E%E5%8A%A0%E7%9B%91%E6%8E%A7%E6%89%A7%E8%A1%8C%E8%80%97%E6%97%B6%E3%80%8B.md)
- [基于JavaAgent的全链路监控三《ByteBuddy操作监控方法字节码》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-12-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E4%B8%89%E3%80%8AByteBuddy%E6%93%8D%E4%BD%9C%E7%9B%91%E6%8E%A7%E6%96%B9%E6%B3%95%E5%AD%97%E8%8A%82%E7%A0%81%E3%80%8B.md)

<details><summary><a>👉显示更多</a></summary></br>

- [基于JavaAgent的全链路监控四《JVM内存与GC信息》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-13-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E5%9B%9B%E3%80%8AJVM%E5%86%85%E5%AD%98%E4%B8%8EGC%E4%BF%A1%E6%81%AF%E3%80%8B.md)
- [基于JavaAgent的全链路监控五《ThreadLocal链路追踪》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-14-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E4%BA%94%E3%80%8AThreadLocal%E9%93%BE%E8%B7%AF%E8%BF%BD%E8%B8%AA%E3%80%8B.md)
- [基于JavaAgent的全链路监控六《开发应用级监控》](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/agent/2019-07-15-%E5%9F%BA%E4%BA%8EJavaAgent%E7%9A%84%E5%85%A8%E9%93%BE%E8%B7%AF%E7%9B%91%E6%8E%A7%E5%85%AD%E3%80%8A%E5%BC%80%E5%8F%91%E5%BA%94%E7%94%A8%E7%BA%A7%E7%9B%91%E6%8E%A7%E3%80%8B.md)

</details>

### 7.3 文档(ASM-DOC) - 👉[**在线阅读**](https://bugstack.cn/md/bytecode/asm-document/1%E5%BC%95%E8%A8%80.html)

- [第 1 章 - 引言](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/1%E5%BC%95%E8%A8%80.md)
    
- [第 2 章 - 类](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/2.0%E7%B1%BB.md)
   
    - [2.1结构](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/2.1%E7%BB%93%E6%9E%84.md)
    - [2.2接口和组件](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/2.2%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%BB%84%E4%BB%B6.md)
    - [2.3工具](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/2.3%E5%B7%A5%E5%85%B7.md)   
 
<details><summary><a>👉显示更多</a></summary></br> 
    
- [第 3 章 - 方法](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/3.0%E6%96%B9%E6%B3%95.md)
    
    - [3.1结构](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/3.1%E7%BB%93%E6%9E%84.md)
    - [3.2接口和组件](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/3.2%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%BB%84%E4%BB%B6.md)
    - [3.3工具](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/3.3%E5%B7%A5%E5%85%B7.md)

- [第 4 章 - 元数据](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/4.0%E5%85%83%E6%95%B0%E6%8D%AE.md)

    - [4.1泛型](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/4.1%E6%B3%9B%E5%9E%8B.md)
    - [4.2注释](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/4.2%E6%B3%A8%E9%87%8A.md)
    - [4.3调试](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/4.3%E8%B0%83%E8%AF%95.md)
    
- [第 5 章 - 后向兼容](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/5.0%E5%90%8E%E5%90%91%E5%85%BC%E5%AE%B9.md)

    - [5.1引言](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/5.1%E5%BC%95%E8%A8%80.md)
    - [5.2规则](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/5.2%E8%A7%84%E5%88%99.md)
    
- [第 6 章 - 类](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/6.0%E7%B1%BB.md)

    - [6.1接口和组件](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/6.1%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%BB%84%E4%BB%B6.md)
    - [6.2组件合成](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/6.2%E7%BB%84%E4%BB%B6%E5%90%88%E6%88%90.md)
    
- [第 7 章 - 方法](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/7.0%E6%96%B9%E6%B3%95.md)
    
    - [7.1接口和组件](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/7.1%E6%8E%A5%E5%8F%A3%E5%92%8C%E7%BB%84%E4%BB%B6.md)
    - [7.2组件合成](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/7.2%E7%BB%84%E4%BB%B6%E5%90%88%E6%88%90.md)

- [第 8 章 - 方法分析](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/8.0%E6%96%B9%E6%B3%95%E5%88%86%E6%9E%90.md)

    - [8.1介绍](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/8.1%E4%BB%8B%E7%BB%8D.md)
    - [8.2组件与接口](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/8.2%E7%BB%84%E4%BB%B6%E4%B8%8E%E6%8E%A5%E5%8F%A3.md)
    
- [第 9 章 - 元数据](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/9.0%E5%85%83%E6%95%B0%E6%8D%AE.md)

    - [9.1泛型](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/9.1%E6%B3%9B%E5%9E%8B.md)
    - [9.2注释](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/9.2%E6%B3%A8%E9%87%8A.md)
    - [9.3调试](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/9.3%E8%B0%83%E8%AF%95.md)
    
- [第 10 章 - 后向兼容](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/10.0%E5%90%8E%E5%90%91%E5%85%BC%E5%AE%B9.md)

    - [10.1介绍](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/10.1%E4%BB%8B%E7%BB%8D.md)
    - [10.2规则](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/10.2%E8%A7%84%E5%88%99.md)
    
- A. 附录

    - [A.1字节代码指](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/A.1%E5%AD%97%E8%8A%82%E4%BB%A3%E7%A0%81%E6%8C%87.md)
    - [A.2子例程](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/A.2%E5%AD%90%E4%BE%8B%E7%A8%8B.md)
    - [A.3属性](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/A.3%E5%B1%9E%E6%80%A7.md)
    - [A.4规则](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/A.4%E8%A7%84%E5%88%99.md)
    - [A.5性能](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/A.5%E6%80%A7%E8%83%BD.md)
    - [JVM-指令表](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/bytecode/asm-document/JVM-%E6%8C%87%E4%BB%A4%E8%A1%A8.md)

</details>

## 8. 实战项目

### 8.1 IM Netty 仿PC端微信 - 👉[**在线阅读**](https://bugstack.cn/md/project/im/2020-03-04-%E3%80%8ANetty+JavaFx%E5%AE%9E%E6%88%98%EF%BC%9A%E4%BB%BF%E6%A1%8C%E9%9D%A2%E7%89%88%E5%BE%AE%E4%BF%A1%E8%81%8A%E5%A4%A9%E3%80%8B.html)

- [介绍](https://bugstack.cn/md/project/im/2020-03-04-%E3%80%8ANetty+JavaFx%E5%AE%9E%E6%88%98%EF%BC%9A%E4%BB%BF%E6%A1%8C%E9%9D%A2%E7%89%88%E5%BE%AE%E4%BF%A1%E8%81%8A%E5%A4%A9%E3%80%8B.html)
- 第 1 章 - UI开发
    - [1.0：专栏学习简述以及全套源码获取](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.1：PC端微信页面拆分及JavaFx使用](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.2：登陆框体实现(结构定义、输入框和登陆)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.3：登陆框体事件与接口](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.4：聊天框体实现一(整体结构定义、侧边栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.5：聊天框体实现二(对话栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.6：聊天框体实现三(对话聊天框)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.7：聊天框体实现四(好友栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.8：聊天框体实现五(好友填充框)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.9：聊天框体事件定义](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.10：练习篇-聊天表情框体实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [1.11：解答篇-聊天表情框体实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)

<details><summary><a>👉显示更多</a></summary></br>    
    
- 第 2 章 - 架构设计
    - [2.1：服务端架构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [2.2：通信协议包定义](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [2.3：客户端架构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [2.4：数据库表结构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
- 第 3 章 - 功能实现 
    - [3.1：登陆功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.2：搜索和添加好友](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.3：对话通知与应答](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.4：用户与好友通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.5：用户与群组通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.6：断线重连恢复通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.7：服务端控制台搭建](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.8：练习篇-聊天表情发送功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    - [3.9：解答篇-聊天表情发送功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)

</details>

### 8.2 SpringBoot 中间件设计和开发 - 👉[**在线阅读**](https://bugstack.cn/md/project/springboot-middleware/2021-03-31-%E3%80%8ASpringBoot%20%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91%E3%80%8B%E4%B8%93%E6%A0%8F%E5%B0%8F%E5%86%8C%E4%B8%8A%E7%BA%BF%E5%95%A6%EF%BC%81.html)

- [中间件小册介绍](https://bugstack.cn/md/project/springboot-middleware/2021-03-31-%E3%80%8ASpringBoot%20%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91%E3%80%8B%E4%B8%93%E6%A0%8F%E5%B0%8F%E5%86%8C%E4%B8%8A%E7%BA%BF%E5%95%A6%EF%BC%81.html)
- 第 1 部分 - 开篇
    - [第 1 章 什么是中间件](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%201%20%E7%AB%A0%20%E4%BB%80%E4%B9%88%E6%98%AF%E4%B8%AD%E9%97%B4%E4%BB%B6.html)
    - [第 2 章 【重要】小册学习介绍&源码授权](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%202%20%E7%AB%A0%20%E3%80%90%E9%87%8D%E8%A6%81%E3%80%91%E5%B0%8F%E5%86%8C%E5%AD%A6%E4%B9%A0%E4%BB%8B%E7%BB%8D&%E6%BA%90%E7%A0%81%E6%8E%88%E6%9D%83.html)
- 第 2 部分 - 服务治理
    - [第 3 章 服务治理，统一白名单控制](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%203%20%E7%AB%A0%20%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%EF%BC%8C%E7%BB%9F%E4%B8%80%E7%99%BD%E5%90%8D%E5%8D%95%E6%8E%A7%E5%88%B6.html)
    - [第 4 章 服务治理，超时熔断](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%204%20%E7%AB%A0%20%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%EF%BC%8C%E8%B6%85%E6%97%B6%E7%86%94%E6%96%AD.html)
    - [第 5 章 服务治理，调用限流](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%205%20%E7%AB%A0%20%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%EF%BC%8C%E8%B0%83%E7%94%A8%E9%99%90%E6%B5%81.html)
    - [第 6 章 服务治理，自定义拦截方法](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%206%20%E7%AB%A0%20%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%EF%BC%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8B%A6%E6%88%AA%E6%96%B9%E6%B3%95.html)
- 第 3 部分 - ORM 框架
    - [第 7 章 ORM 框架实现](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%207%20%E7%AB%A0%20ORM%20%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0.html)
    - [第 8 章 ORM 框架与 Spring 集合](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%208%20%E7%AB%A0%20ORM%20%E6%A1%86%E6%9E%B6%E4%B8%8E%20Spring%20%E9%9B%86%E5%90%88.html)
    - [第 9 章 结合 SpringBoot 开发 ORM Starter](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%209%20%E7%AB%A0%20%E7%BB%93%E5%90%88%20SpringBoot%20%E5%BC%80%E5%8F%91%20ORM%20Starter.html)
    - [第 10 章 ES-JDBC 查询引擎](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2010%20%E7%AB%A0%20ES-JDBC%20%E6%9F%A5%E8%AF%A2%E5%BC%95%E6%93%8E.html)
    - [第 11 章 ES SpringBoot Starter 服务框架](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2011%20%E7%AB%A0%20ES%20SpringBoot%20Starter%20%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6.html)
    
<details><summary><a>👉显示更多</a></summary></br>   
    
- 第 4 部分 - 分布式组件
    - [第 12 章 RPC 框架实现](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2012%20%E7%AB%A0%20RPC%20%E6%A1%86%E6%9E%B6%E5%AE%9E%E7%8E%B0.html)
    - [第 13 章 数据库路由组件](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2013%20%E7%AB%A0%20%E6%95%B0%E6%8D%AE%E5%BA%93%E8%B7%AF%E7%94%B1%E7%BB%84%E4%BB%B6.html)
    - [第 14 章 Redis 简化使用封装](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2014%20%E7%AB%A0%20Redis%20%E7%AE%80%E5%8C%96%E4%BD%BF%E7%94%A8%E5%B0%81%E8%A3%85.html)
    - [第 15 章 分布式任务调度](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2015%20%E7%AB%A0%20%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6.html)
- 第 5 部分 - 字节码应用
    - [第 16 章 非入侵监控设计，ASM 字节码插桩](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2016%20%E7%AB%A0%20%E9%9D%9E%E5%85%A5%E4%BE%B5%E7%9B%91%E6%8E%A7%E8%AE%BE%E8%AE%A1%EF%BC%8CASM%20%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9.html)
    - [第 17 章 非入侵监控设计，JVMTI 定位代码](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2017%20%E7%AB%A0%20%E9%9D%9E%E5%85%A5%E4%BE%B5%E7%9B%91%E6%8E%A7%E8%AE%BE%E8%AE%A1%EF%BC%8CJVMTI%20%E5%AE%9A%E4%BD%8D%E4%BB%A3%E7%A0%81.html)
    - [第 18 章 基于IDEA插件开发和字节码插桩技术，采集研发过程中代码执行信息](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2018%20%E7%AB%A0%20%E5%9F%BA%E4%BA%8EIDEA%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%92%8C%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E6%8A%80%E6%9C%AF%EF%BC%8C%E9%87%87%E9%9B%86%E7%A0%94%E5%8F%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E4%BF%A1%E6%81%AF.html)
- 第 6 部分
    - [第 19 章 后记](https://bugstack.cn/md/project/springboot-middleware/%E7%AC%AC%2019%20%E7%AB%A0%20%E5%90%8E%E8%AE%B0.html)

</details>

### 8.3 Lottery 分布式抽奖系统 - 👉[**在线阅读**](https://bugstack.cn/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.html)

- [Lottery 分布式抽奖系统介绍](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.md)

- 第 1 部分 大厂规范
    
    - [第01节：大厂码农开发基础](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-1/%E7%AC%AC01%E8%8A%82%EF%BC%9A%E5%A4%A7%E5%8E%82%E7%A0%81%E5%86%9C%E5%BC%80%E5%8F%91%E5%9F%BA%E7%A1%80.md)
    - [第02节：需求怎么来的](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-1/%E7%AC%AC02%E8%8A%82%EF%BC%9A%E9%9C%80%E6%B1%82%E6%80%8E%E4%B9%88%E6%9D%A5%E7%9A%84.md)
    - [第03节：系统架构设计](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-1/%E7%AC%AC03%E8%8A%82%EF%BC%9A%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1.md)
    - [第04节：进入开发阶段](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-1/%E7%AC%AC04%E8%8A%82%EF%BC%9A%E8%BF%9B%E5%85%A5%E5%BC%80%E5%8F%91%E9%98%B6%E6%AE%B5.md)
    - [第05节：系统上线维护](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-1/%E7%AC%AC05%E8%8A%82%EF%BC%9A%E7%B3%BB%E7%BB%9F%E4%B8%8A%E7%BA%BF%E7%BB%B4%E6%8A%A4.md)
    
- 第 2 部分 领域开发

    - [第01节：环境、配置、规范](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-2/%E7%AC%AC01%E8%8A%82%EF%BC%9A%E7%8E%AF%E5%A2%83%E3%80%81%E9%85%8D%E7%BD%AE%E3%80%81%E8%A7%84%E8%8C%83.md)
    - [第02节：搭建DDD四层架构](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC02%E8%8A%82%EF%BC%9A%E6%90%AD%E5%BB%BADDD%E5%9B%9B%E5%B1%82%E6%9E%B6%E6%9E%84.html)
    - [第03节：跑通广播模式RPC过程调用](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC03%E8%8A%82%EF%BC%9A%E8%B7%91%E9%80%9A%E5%B9%BF%E6%92%AD%E6%A8%A1%E5%BC%8FRPC%E8%BF%87%E7%A8%8B%E8%B0%83%E7%94%A8.html)
    - [第04节：抽奖活动策略库表设计](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC04%E8%8A%82%EF%BC%9A%E6%8A%BD%E5%A5%96%E6%B4%BB%E5%8A%A8%E7%AD%96%E7%95%A5%E5%BA%93%E8%A1%A8%E8%AE%BE%E8%AE%A1.html)
    - [第05节：抽奖策略领域模块开发](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC05%E8%8A%82%EF%BC%9A%E6%8A%BD%E5%A5%96%E7%AD%96%E7%95%A5%E9%A2%86%E5%9F%9F%E6%A8%A1%E5%9D%97%E5%BC%80%E5%8F%91.html)
    - [第06节：模板模式处理抽奖流程](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC06%E8%8A%82%EF%BC%9A%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F%E5%A4%84%E7%90%86%E6%8A%BD%E5%A5%96%E6%B5%81%E7%A8%8B.html)
    - [第07节：简单工厂搭建发奖领域](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC07%E8%8A%82%EF%BC%9A%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%90%AD%E5%BB%BA%E5%8F%91%E5%A5%96%E9%A2%86%E5%9F%9F.html)
    - [第08节：活动领域的配置与状态](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC08%E8%8A%82%EF%BC%9A%E6%B4%BB%E5%8A%A8%E9%A2%86%E5%9F%9F%E7%9A%84%E9%85%8D%E7%BD%AE%E4%B8%8E%E7%8A%B6%E6%80%81.html)
    - [第09节：ID生成策略领域开发](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC09%E8%8A%82%EF%BC%9AID%E7%94%9F%E6%88%90%E7%AD%96%E7%95%A5%E9%A2%86%E5%9F%9F%E5%BC%80%E5%8F%91.html)
    - [第10节：实现和使用分库分表](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC10%E8%8A%82%EF%BC%9A%E5%AE%9E%E7%8E%B0%E5%92%8C%E4%BD%BF%E7%94%A8%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8.html)
    - [第11节：声明事务领取活动领域开发](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC11%E8%8A%82%EF%BC%9A%E5%A3%B0%E6%98%8E%E4%BA%8B%E5%8A%A1%E9%A2%86%E5%8F%96%E6%B4%BB%E5%8A%A8%E9%A2%86%E5%9F%9F%E5%BC%80%E5%8F%91.html)
    - [第12节：在应用层编排抽奖过程](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC12%E8%8A%82%EF%BC%9A%E5%9C%A8%E5%BA%94%E7%94%A8%E5%B1%82%E7%BC%96%E6%8E%92%E6%8A%BD%E5%A5%96%E8%BF%87%E7%A8%8B.html)
    - [第13节：规则引擎量化人群参与活动](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC13%E8%8A%82%EF%BC%9A%E8%A7%84%E5%88%99%E5%BC%95%E6%93%8E%E9%87%8F%E5%8C%96%E4%BA%BA%E7%BE%A4%E5%8F%82%E4%B8%8E%E6%B4%BB%E5%8A%A8.html)
    - [第14节：门面接口封装和对象转换](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC14%E8%8A%82%EF%BC%9A%E9%97%A8%E9%9D%A2%E6%8E%A5%E5%8F%A3%E5%B0%81%E8%A3%85%E5%92%8C%E5%AF%B9%E8%B1%A1%E8%BD%AC%E6%8D%A2.html)
    - [第15节：搭建MQ消息组件Kafka服务环境](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC15%E8%8A%82%EF%BC%9A%E6%90%AD%E5%BB%BAMQ%E6%B6%88%E6%81%AF%E7%BB%84%E4%BB%B6Kafka%E6%9C%8D%E5%8A%A1%E7%8E%AF%E5%A2%83.html)
    - [第16节：使用MQ解耦抽奖发货流程](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC16%E8%8A%82%EF%BC%9A%E4%BD%BF%E7%94%A8MQ%E8%A7%A3%E8%80%A6%E6%8A%BD%E5%A5%96%E5%8F%91%E8%B4%A7%E6%B5%81%E7%A8%8B.html)
    - [第17节：引入xxl-job处理活动状态扫描](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC17%E8%8A%82%EF%BC%9A%E5%BC%95%E5%85%A5xxl-job%E5%A4%84%E7%90%86%E6%B4%BB%E5%8A%A8%E7%8A%B6%E6%80%81%E6%89%AB%E6%8F%8F.html)
    - [第18节：扫描库表补偿发货单MQ消息](https://bugstack.cn/md/project/lottery/Part-2/%E7%AC%AC18%E8%8A%82%EF%BC%9A%E6%89%AB%E6%8F%8F%E5%BA%93%E8%A1%A8%E8%A1%A5%E5%81%BF%E5%8F%91%E8%B4%A7%E5%8D%95MQ%E6%B6%88%E6%81%AF.html)
    - [第19节：设计滑动库存分布式锁处理活动秒杀](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-2/%E7%AC%AC19%E8%8A%82%EF%BC%9A%E8%AE%BE%E8%AE%A1%E6%BB%91%E5%8A%A8%E5%BA%93%E5%AD%98%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%A4%84%E7%90%86%E6%B4%BB%E5%8A%A8%E7%A7%92%E6%9D%80.md)

- 第 3 部分 运营后台

    - [第01节：UI工程搭建](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-3/%E7%AC%AC01%E8%8A%82%EF%BC%9AUI%E5%B7%A5%E7%A8%8B%E6%90%AD%E5%BB%BA.md)
    - [第02节：活动列表数据展示](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-3/%E7%AC%AC02%E8%8A%82%EF%BC%9A%E6%B4%BB%E5%8A%A8%E5%88%97%E8%A1%A8%E6%95%B0%E6%8D%AE%E5%B1%95%E7%A4%BA.md)

<details><summary><a>👉显示更多</a></summary></br> 

- 第 4 部分 应用场景

    - [第01节：搭建微信公众号网关服务](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-4/%E7%AC%AC01%E8%8A%82%EF%BC%9A%E6%90%AD%E5%BB%BA%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E7%BD%91%E5%85%B3%E6%9C%8D%E5%8A%A1.md)
    - [第02节：vue H5 大转盘抽奖](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-4/%E7%AC%AC02%E8%8A%82%EF%BC%9Avue%20H5%20%E5%A4%A7%E8%BD%AC%E7%9B%98%E6%8A%BD%E5%A5%96.md)

- 第 5 部分 系统运维

    - [第01节：在云服务器部署 Docker](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC01%E8%8A%82%EF%BC%9A%E5%9C%A8%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%83%A8%E7%BD%B2%20Docker.md)
    - [第02节：部署环境 Redis](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC02%E8%8A%82%EF%BC%9A%E9%83%A8%E7%BD%B2%E7%8E%AF%E5%A2%83%20Redis.md)
    - [第03节：部署环境 Kafka](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC03%E8%8A%82%EF%BC%9A%E9%83%A8%E7%BD%B2%E7%8E%AF%E5%A2%83%20Kafka.md)
    - [第04节：部署环境 Mysql](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC04%E8%8A%82%EF%BC%9A%E9%83%A8%E7%BD%B2%E7%8E%AF%E5%A2%83%20Mysql.md)
    - [第05节：部署环境 xxl-job](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC05%E8%8A%82%EF%BC%9A%E9%83%A8%E7%BD%B2%E7%8E%AF%E5%A2%83%20xxl-job.md)
    - [第06节：部署环境 nacos](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/project/lottery/Part-5/%E7%AC%AC06%E8%8A%82%EF%BC%9A%E9%83%A8%E7%BD%B2%E7%8E%AF%E5%A2%83%20nacos.md)
    - [第07节：部署环境 Elasticsearch、Kibana](#)
    - [第08节：部署环境 canal 同步数据到 ES](#)
    
</details>

## 9. 部署 - 👉[**在线阅读**](https://bugstack.cn/md/devops/2019-08-12-windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85elasticsearch6.2.2.html)

- [windows环境下安装elasticsearch6.2.2](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2019-08-12-windows%E7%8E%AF%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%85elasticsearch6.2.2.md)
- [elasticsearch-head插件安装](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2019-08-13-elasticsearch-head%E6%8F%92%E4%BB%B6%E5%AE%89%E8%A3%85.md)
- [并不想吹牛皮，但！为了把Github博客粉丝转移到公众号，我干了！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2019-11-23-%E5%B9%B6%E4%B8%8D%E6%83%B3%E5%90%B9%E7%89%9B%E7%9A%AE%EF%BC%8C%E4%BD%86%EF%BC%81%E4%B8%BA%E4%BA%86%E6%8A%8AGithub%E5%8D%9A%E5%AE%A2%E7%B2%89%E4%B8%9D%E8%BD%AC%E7%A7%BB%E5%88%B0%E5%85%AC%E4%BC%97%E5%8F%B7%EF%BC%8C%E6%88%91%E5%B9%B2%E4%BA%86%EF%BC%81.md)
- [20年3月27日，Github被攻击。我的GitPage博客也挂了，紧急修复之路，也教会你搭建 Jekyll 博客！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2020-03-28-GithubAndMyBlogAttacked.md)

<details><summary><a>👉显示更多</a></summary></br>

- [《Netty+JavaFx实战：仿桌面版微信聊天》代码开源+上云部署+视频讲解](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2020-04-25-%E3%80%8ANetty%2BJavaFx%E5%AE%9E%E6%88%98%EF%BC%9A%E4%BB%BF%E6%A1%8C%E9%9D%A2%E7%89%88%E5%BE%AE%E4%BF%A1%E8%81%8A%E5%A4%A9%E3%80%8B%E4%BB%A3%E7%A0%81%E5%BC%80%E6%BA%90%2B%E4%B8%8A%E4%BA%91%E9%83%A8%E7%BD%B2%2B%E8%A7%86%E9%A2%91%E8%AE%B2%E8%A7%A3.md)
- [自建云盘存储PDF书籍支持在线预览和下载](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2020-05-10-%E8%87%AA%E5%BB%BA%E4%BA%91%E7%9B%98%E5%AD%98%E5%82%A8PDF%E4%B9%A6%E7%B1%8D%E6%94%AF%E6%8C%81%E5%9C%A8%E7%BA%BF%E9%A2%84%E8%A7%88%E5%92%8C%E4%B8%8B%E8%BD%BD.md)
- [一天建4个，小傅哥教你搭博客！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2021-01-24-%E4%B8%80%E5%A4%A9%E5%BB%BA4%E4%B8%AA%EF%BC%8C%E5%B0%8F%E5%82%85%E5%93%A5%E6%95%99%E4%BD%A0%E6%90%AD%E5%8D%9A%E5%AE%A2%EF%BC%81.md)
- [Cloudreve 自建云盘实践，我说了没人能限得了我的容量和速度！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2021-04-11-Cloudreve%20%E8%87%AA%E5%BB%BA%E4%BA%91%E7%9B%98%E5%AE%9E%E8%B7%B5%EF%BC%8C%E6%88%91%E8%AF%B4%E4%BA%86%E6%B2%A1%E4%BA%BA%E8%83%BD%E9%99%90%E5%BE%97%E4%BA%86%E6%88%91%E7%9A%84%E5%AE%B9%E9%87%8F%E5%92%8C%E9%80%9F%E5%BA%A6%EF%BC%81.md)
- [【经验分享】码农使用云服务学习，部环境、开端口、配域名、弄SSL、搭博客](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2021-06-04-%E3%80%90%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB%E3%80%91%E7%A0%81%E5%86%9C%E4%BD%BF%E7%94%A8%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%AD%A6%E4%B9%A0%EF%BC%8C%E9%83%A8%E7%8E%AF%E5%A2%83%E3%80%81%E5%BC%80%E7%AB%AF%E5%8F%A3%E3%80%81%E9%85%8D%E5%9F%9F%E5%90%8D%E3%80%81%E5%BC%84SSL%E3%80%81%E6%90%AD%E5%8D%9A%E5%AE%A2%EF%BC%81.md) 
- [关于怎么使用 webhooks 自动部署博客，详细教程文档！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2021-11-07-%E5%85%B3%E4%BA%8E%E6%80%8E%E4%B9%88%E4%BD%BF%E7%94%A8%20webhooks%20%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%8D%9A%E5%AE%A2%EF%BC%8C%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B%E6%96%87%E6%A1%A3%EF%BC%81.md)
- [教小白使用 docsify，搭建一个贼简单的所见即所得博客！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/devops/2022-03-04-%E6%95%99%E5%B0%8F%E7%99%BD%E4%BD%BF%E7%94%A8%20docsify%EF%BC%8C%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA%E8%B4%BC%E7%AE%80%E5%8D%95%E7%9A%84%E6%89%80%E8%A7%81%E5%8D%B3%E6%89%80%E5%BE%97%E5%8D%9A%E5%AE%A2%EF%BC%81.md)

</details>


## 10. PDF 下载

- [《Java 面经手册》](https://download.csdn.net/download/Yao__Shun__Yu/14932325)
- [《手撸 Spring》](https://download.csdn.net/download/Yao__Shun__Yu/21009038)
- [《重学Java设计模式》](https://download.csdn.net/download/Yao__Shun__Yu/19265731)
- [《字节码编程》](https://download.csdn.net/download/Yao__Shun__Yu/12505051)
- [《IDEA Plugin 开发手册》](https://download.csdn.net/download/Yao__Shun__Yu/77484299)

## 11. 关于

### 11.1 关于自己 - 👉[**在线阅读**](https://bugstack.cn/md/about/me/about-me.html)

- [大学四年到毕业工作5年的学习路线资源汇总](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-03-31-%E5%A4%A7%E5%AD%A6%E5%9B%9B%E5%B9%B4%E5%88%B0%E6%AF%95%E4%B8%9A%E5%B7%A5%E4%BD%9C5%E5%B9%B4%E7%9A%84%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF%E8%B5%84%E6%BA%90%E6%B1%87%E6%80%BB.md)
- [12天，这本《重学Java设计模式》PDF书籍下载量9k，新增粉丝1400人，Github上全球推荐榜](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-07-25-12%E5%A4%A9%EF%BC%8C%E8%BF%99%E6%9C%AC%E3%80%8A%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8BPDF%E4%B9%A6%E7%B1%8D%E4%B8%8B%E8%BD%BD%E9%87%8F9k%EF%BC%8C%E6%96%B0%E5%A2%9E%E7%B2%89%E4%B8%9D1400%E4%BA%BA%EF%BC%8CGithub%E4%B8%8A%E5%85%A8%E7%90%83%E6%8E%A8%E8%8D%90%E6%A6%9C.md)
- [13年毕业，用两年时间从外包走进互联网大厂](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-08-25-13%E5%B9%B4%E6%AF%95%E4%B8%9A%EF%BC%8C%E7%94%A8%E4%B8%A4%E5%B9%B4%E6%97%B6%E9%97%B4%E4%BB%8E%E5%A4%96%E5%8C%85%E8%B5%B0%E8%BF%9B%E4%BA%92%E8%81%94%E7%BD%91%E5%A4%A7%E5%8E%82.md)

<details><summary><a>👉显示更多</a></summary></br> 

- [让人怪不好意思的，粉丝破万，用了1年！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-10-09-%E8%AE%A9%E4%BA%BA%E6%80%AA%E4%B8%8D%E5%A5%BD%E6%84%8F%E6%80%9D%E7%9A%84%EF%BC%8C%E7%B2%89%E4%B8%9D%E7%A0%B4%E4%B8%87%EF%BC%8C%E7%94%A8%E4%BA%861%E5%B9%B4%EF%BC%81.md)
- [今天你写博客了吗](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-10-25-%E4%BB%8A%E5%A4%A9%E4%BD%A0%E5%86%99%E5%8D%9A%E5%AE%A2%E4%BA%86%E5%90%97.md)
- [刚毕业不久，接私活赚了2万块！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-11-01-%E5%88%9A%E6%AF%95%E4%B8%9A%E4%B8%8D%E4%B9%85%EF%BC%8C%E6%8E%A5%E7%A7%81%E6%B4%BB%E8%B5%9A%E4%BA%862%E4%B8%87%E5%9D%97%EF%BC%81.md)
- [北漂码农的我，把在大城市过成了屯子一样舒服，哈哈哈哈哈！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-11-29-%E5%8C%97%E6%BC%82%E7%A0%81%E5%86%9C%E7%9A%84%E6%88%91%EF%BC%8C%E6%8A%8A%E5%9C%A8%E5%A4%A7%E5%9F%8E%E5%B8%82%E8%BF%87%E6%88%90%E4%BA%86%E5%B1%AF%E5%AD%90%E4%B8%80%E6%A0%B7%E8%88%92%E6%9C%8D%EF%BC%8C%E5%93%88%E5%93%88%E5%93%88%E5%93%88%E5%93%88%EF%BC%81.md)
- [2020总结 | 作为技术号主的一年！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2020-12-27-2020%E6%80%BB%E7%BB%93%EF%BC%8C%E4%BD%9C%E4%B8%BA%E6%8A%80%E6%9C%AF%E5%8F%B7%E4%B8%BB%E7%9A%84%E4%B8%80%E5%B9%B4%EF%BC%81.md)
- [这一年，想踏码进货一样！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-01-31-%E8%BF%99%E4%B8%80%E5%B9%B4%EF%BC%8C%E6%83%B3%E8%B8%8F%E7%A0%81%E8%BF%9B%E8%B4%A7%E4%B8%80%E6%A0%B7%EF%BC%81.md)
- [小傅哥，一个有副业的码农](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-05-26-%E5%B0%8F%E5%82%85%E5%93%A5%EF%BC%8C%E4%B8%80%E4%B8%AA%E6%9C%89%E5%89%AF%E4%B8%9A%E7%9A%84%E7%A0%81%E5%86%9C.md)
- [我，有10万+粉丝啦！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-06-20-%E6%88%91%EF%BC%8C%E6%9C%8910%E4%B8%87%2B%E7%B2%89%E4%B8%9D%E5%95%A6%EF%BC%81.md)
- [以一己之力，生抗美团技术博客！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-07-03-%E4%BB%A5%E4%B8%80%E5%B7%B1%E4%B9%8B%E5%8A%9B%EF%BC%8C%E7%94%9F%E6%8A%97%E7%BE%8E%E5%9B%A2%E6%8A%80%E6%9C%AF%E5%8D%9A%E5%AE%A2%EF%BC%81.md)
- [我在CSDN赚了1.2万](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-09-05-%E6%88%91%E5%9C%A8CSDN%E8%B5%9A%E4%BA%861.2%E4%B8%87.md)
- [炸！1024，小傅哥的博客升级啦，文章开源、支持PR，冲哇！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-10-24-%E7%82%B8%EF%BC%811024%EF%BC%8C%E5%B0%8F%E5%82%85%E5%93%A5%E7%9A%84%E5%8D%9A%E5%AE%A2%E5%8D%87%E7%BA%A7%E5%95%A6%EF%BC%8C%E6%96%87%E7%AB%A0%E5%BC%80%E6%BA%90%E3%80%81%E6%94%AF%E6%8C%81PR%EF%BC%8C%E5%86%B2%E5%93%87%EF%BC%81.md)
- [CodeGuide 300+文档、100+代码库，一个指导程序员写代码的，Github 仓库开源啦！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2021-11-14-CodeGuide%E5%BC%80%E6%BA%90%E4%BB%93%E5%BA%93.md)
- [2021年，小傅哥の年终总结！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2022-01-27-2021%E5%B9%B4%EF%BC%8C%E5%B0%8F%E5%82%85%E5%93%A5%E3%81%AE%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93%EF%BC%81.md)
- [被掘金读者举报，侵权国外资料，但却是一次不错的经历！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/me/2022-05-22-copyright-violation.md)

</details>

### 11.2 关于学习 - 👉[**在线阅读**](https://bugstack.cn/md/about/study/2020-04-30-%E8%AE%B2%E9%81%93%E7%90%86%EF%BC%8C%E5%8F%AA%E8%A6%81%E4%BD%A0%E6%98%AF%E4%B8%80%E4%B8%AA%E7%88%B1%E6%8A%98%E8%85%BE%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98%EF%BC%8C%E6%AF%95%E4%B8%9A%E6%89%BE%E5%B7%A5%E4%BD%9C%E7%9C%9F%E7%9A%84%E4%B8%8D%E9%9C%80%E8%A6%81%E5%86%8D%E8%8A%B1%E9%92%B1%E5%9F%B9%E8%AE%AD.html)

- [讲道理，只要你是一个爱折腾的程序员，毕业找工作真的不需要再花钱培训](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-04-30-%E8%AE%B2%E9%81%93%E7%90%86%EF%BC%8C%E5%8F%AA%E8%A6%81%E4%BD%A0%E6%98%AF%E4%B8%80%E4%B8%AA%E7%88%B1%E6%8A%98%E8%85%BE%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98%EF%BC%8C%E6%AF%95%E4%B8%9A%E6%89%BE%E5%B7%A5%E4%BD%9C%E7%9C%9F%E7%9A%84%E4%B8%8D%E9%9C%80%E8%A6%81%E5%86%8D%E8%8A%B1%E9%92%B1%E5%9F%B9%E8%AE%AD.md)
- [为了省钱，我用1天时间把PHP学了！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-10-11-%E4%B8%BA%E4%BA%86%E7%9C%81%E9%92%B1%EF%BC%8C%E6%88%91%E7%94%A81%E5%A4%A9%E6%97%B6%E9%97%B4%E6%8A%8APHP%E5%AD%A6%E4%BA%86%EF%BC%81.md)
- [UML类图还不懂？来看看这版乡村爱情类图，一把学会！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-10-18-UML%E7%B1%BB%E5%9B%BE%E8%BF%98%E4%B8%8D%E6%87%82%EF%BC%9F%E6%9D%A5%E7%9C%8B%E7%9C%8B%E8%BF%99%E7%89%88%E4%B9%A1%E6%9D%91%E7%88%B1%E6%83%85%E7%B1%BB%E5%9B%BE%EF%BC%8C%E4%B8%80%E6%8A%8A%E5%AD%A6%E4%BC%9A%EF%BC%81.md)

<details><summary><a>👉显示更多</a></summary></br>

- [一个简单的能力，决定你是否会学习！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-11-08-%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E8%83%BD%E5%8A%9B%EF%BC%8C%E5%86%B3%E5%AE%9A%E4%BD%A0%E6%98%AF%E5%90%A6%E4%BC%9A%E5%AD%A6%E4%B9%A0%EF%BC%81.md)
- [90% 的程序员，都没用过多线程和锁，怎么成为架构师？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-12-06-90Per%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98%EF%BC%8C%E9%83%BD%E6%B2%A1%E7%94%A8%E8%BF%87%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%92%8C%E9%94%81%EF%BC%8C%E6%80%8E%E4%B9%88%E6%88%90%E4%B8%BA%E6%9E%B6%E6%9E%84%E5%B8%88%EF%BC%9F.md)
- [码德需求，这不就是产品给我留的数学作业！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-12-13-%E7%A0%81%E5%BE%B7%E9%9C%80%E6%B1%82%EF%BC%8C%E8%BF%99%E4%B8%8D%E5%B0%B1%E6%98%AF%E4%BA%A7%E5%93%81%E7%BB%99%E6%88%91%E7%95%99%E7%9A%84%E6%95%B0%E5%AD%A6%E4%BD%9C%E4%B8%9A%EF%BC%81.md)
- [工作3年，看啥资料能月薪30K？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-12-20-%E5%B7%A5%E4%BD%9C3%E5%B9%B4%EF%BC%8C%E7%9C%8B%E5%95%A5%E8%B5%84%E6%96%99%E8%83%BD%E6%9C%88%E8%96%AA30K%EF%BC%9F.md)
- [数学，离一个程序员有多近？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-12-20-%E5%B7%A5%E4%BD%9C3%E5%B9%B4%EF%BC%8C%E7%9C%8B%E5%95%A5%E8%B5%84%E6%96%99%E8%83%BD%E6%9C%88%E8%96%AA30K%EF%BC%9F.md)
- [大学毕业要写多少行代码，才能不用花钱培训就找到一份开发工作？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2020-12-20-%E5%B7%A5%E4%BD%9C3%E5%B9%B4%EF%BC%8C%E7%9C%8B%E5%95%A5%E8%B5%84%E6%96%99%E8%83%BD%E6%9C%88%E8%96%AA30K%EF%BC%9F.md)
- [2021版，开发者学习路线图分享](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2021-09-09-2021%E7%89%88%EF%BC%8C%E5%BC%80%E5%8F%91%E8%80%85%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF%E5%9B%BE%E5%88%86%E4%BA%AB.md)
- [你上车，我就把你带成卷王！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/study/2022-02-07-%E4%BD%A0%E4%B8%8A%E8%BD%A6%EF%BC%8C%E6%88%91%E5%B0%B1%E6%8A%8A%E4%BD%A0%E5%B8%A6%E6%88%90%E5%8D%B7%E7%8E%8B%EF%BC%81.md)

</details>

### 11.3 关于工作 - 👉[**在线阅读**](https://bugstack.cn/md/about/job/2020-04-11-%E5%B7%A5%E4%BD%9C%E4%B8%A4%E5%B9%B4%E7%AE%80%E5%8E%86%E5%86%99%E6%88%90%E8%BF%99%E6%A0%B7%EF%BC%8C%E8%B0%81%E8%A6%81%E4%BD%A0%E5%91%80%EF%BC%81.html)

- [工作两年简历写成这样，谁要你呀！](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2020-04-11-%E5%B7%A5%E4%BD%9C%E4%B8%A4%E5%B9%B4%E7%AE%80%E5%8E%86%E5%86%99%E6%88%90%E8%BF%99%E6%A0%B7%EF%BC%8C%E8%B0%81%E8%A6%81%E4%BD%A0%E5%91%80%EF%BC%81.md)
- [程序员为什么热衷于造轮子，升职加薪吗？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2020-09-20-%E7%A8%8B%E5%BA%8F%E5%91%98%E4%B8%BA%E4%BB%80%E4%B9%88%E7%83%AD%E8%A1%B7%E4%BA%8E%E9%80%A0%E8%BD%AE%E5%AD%90%EF%BC%8C%E5%8D%87%E8%81%8C%E5%8A%A0%E8%96%AA%E5%90%97%EF%BC%9F.md)
- [PPT画成这样，述职答辩还能过吗？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2020-09-27-PPT%E7%94%BB%E6%88%90%E8%BF%99%E6%A0%B7%EF%BC%8C%E8%BF%B0%E8%81%8C%E7%AD%94%E8%BE%A9%E8%BF%98%E8%83%BD%E8%BF%87%E5%90%97%EF%BC%9F.md)

<details><summary><a>👉显示更多</a></summary></br>

- [BATJTMD，大厂招聘，都招什么样Java程序员？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2020-11-15-BATJTMD%EF%BC%8C%E5%A4%A7%E5%8E%82%E6%8B%9B%E8%81%98%EF%BC%8C%E9%83%BD%E6%8B%9B%E4%BB%80%E4%B9%88%E6%A0%B7Java%E7%A8%8B%E5%BA%8F%E5%91%98%EF%BC%9F.md)
- [工作3年，看啥资料能月薪30K？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2020-12-20-%E5%B7%A5%E4%BD%9C3%E5%B9%B4%EF%BC%8C%E7%9C%8B%E5%95%A5%E8%B5%84%E6%96%99%E8%83%BD%E6%9C%88%E8%96%AA30K%EF%BC%9F.md)
- [半年筛选了400+份简历，告诉你怎么写会被撩](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2021-02-24-%E5%8D%8A%E5%B9%B4%E7%AD%9B%E9%80%89%E4%BA%86400%2B%E4%BB%BD%E7%AE%80%E5%8E%86%EF%BC%8C%E5%91%8A%E8%AF%89%E4%BD%A0%E6%80%8E%E4%B9%88%E5%86%99%E4%BC%9A%E8%A2%AB%E6%92%A9.md)
- [刚提测就改需求，我是渣男吗？](https://github.com/fuzhengwei/CodeGuide/blob/master/docs/md/about/job/2021-12-02-%E5%88%9A%E6%8F%90%E6%B5%8B%E5%B0%B1%E6%94%B9%E9%9C%80%E6%B1%82%EF%BC%8C%E6%88%91%E6%98%AF%E6%B8%A3%E7%94%B7%E5%90%97.md)

</details>

## 12. 转载分享

建立本开源项目的初衷是基于个人学习与工作中对 Java 相关技术栈的总结记录，在这里也希望能帮助一些在学习 Java 过程中遇到问题的小伙伴，如果您需要转载本仓库的一些文章到自己的博客，请按照以下格式注明出处，谢谢合作。

```
作者：小傅哥
链接：https://bugstack.cn
来源：bugstack虫洞栈
```                  

## 13. 参与贡献

1. 如果您对本项目有任何建议或发现文中内容有误的，欢迎提交 issues 进行指正。
2. 对于文中我没有涉及到知识点，欢迎提交 PR。

## 14. 与我联系

- **加群交流** 本群的宗旨是给大家提供一个良好的技术学习交流平台，所以杜绝一切广告！由于微信群人满 100 之后无法加入，请扫描下方二维码先添加作者 “小傅哥” 微信(fustack)，备注：加群。

<img src="https://bugstack.cn/images/personal/fustack.png" width="180px">

- **公众号(bugstack虫洞栈)** - 沉淀、分享、成长，专注于原创专题案例，以最易学习编程的方式分享知识，让自己和他人都能有所收获。

<img src="https://bugstack.cn/images/personal/qrcode.png" width="180px">

## 15. 致谢

感谢以下人员对本仓库做出的贡献或者对小傅哥的赞赏，当然不仅仅只有这些贡献者，这里就不一一列举了。如果你希望被添加到这个名单中，并且提交过 Issue 或者 PR，请与我联系。

**:seedling: 感谢大家对仓库建设的贡献**

<a href="https://github.com/6freeair2016">
    <img src="https://avatars.githubusercontent.com/u/20253565?v=4" style="border-radius:5px" width="50px">
</a> 
<a href="https://github.com/LittleBrotherFu">
    <img src="https://avatars.githubusercontent.com/u/25544835?v=4" style="border-radius:5px" width="50px">
</a> 
<a href="https://github.com/MichaelHan0228">
    <img src="https://avatars.githubusercontent.com/u/33157567?v=4" style="border-radius:5px" width="50px">
</a>
<a href="https://github.com/lyx0410">
    <img src="https://avatars.githubusercontent.com/u/36250713?v=4" style="border-radius:5px" width="50px">
</a>

---

### README (`docs/README.md`)

---
home: true
heroImage: /images/system/blog-03.png
actionLinks:
- link: /md/other/guide-to-reading.md
  text: 开始阅读 →
  class: primary
#- link: https://wx.zsxq.com/group/48411118851818
#  text: 知识星球
#  class: secondary 
- link: /md/zsxq/introduce.html
  text: 知识星球
  class: secondary  
- link: /md/road-map/road-map.md
  text: 编程路书 👣
  class: secondary   
- link: https://gaga.plus
  text: 编程项目 💐
  class: secondary    
#- link: https://618.gaga.plus
#  text: 9.9元/月(云服务器) ☁️
#  class: secondary
#- link: https://walicode.xiaofuge.cn/
#  text: WaLiCode(平替CodeX)
#  class: secondary
- link: https://ai-agent-guide.xiaofuge.cn/
  text: AI Agent 通识教程
  class: secondary
features:
- title: 沉淀
  details: 承遇朝霞，年少正恰。整装戎马，刻印风华。
- title: 分享
  details: 八表流云澄夜色，九霄华月动春城。
- title: 成长
  details: 心怀天下，声色犬码。生有热烈，藏与俗常。
footer: <a href="http://beian.miit.gov.cn" target="_blank">京ICP备19031103号</a> | <a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11030102010881" style="display:inline-block;text-decoration:none;height:20px;line-height:20px;"><img src="https://bugstack.cn/assets/images/beian.png" style="float:left;"/><p style="float:left;height:20px;line-height:20px;margin-top:5px; color:#939393;">京公网安备 11030102010881号</p></a> | GPL Licensed | Copyright © 2019 小傅哥，All rights reserved. 
---

---

### 我是小傅哥

- :dog: 13年毕业，一线互联网大厂架构师，全网40万+粉编程知识博主。
- :man_technologist: 成长：[关于我，从小白到架构师的成长经历](https://www.bilibili.com/video/BV1FF41137q5)
- :bus: 作品：[`CodeGuide | 程序员编码指南`](https://github.com/fuzhengwei/CodeGuide) | [`RoadMap 编程路书`](https://github.com/fuzhengwei/RoadMap) | [`Java 数据结构和算法`](https://github.com/fuzhengwei/java-algorithms) | [`IM 仿微信`](https://github.com/fuzhengwei/NaiveChat) | [`Java 面经手册`](https://github.com/fuzhengwei/interview) | [`IntelliJ IDEA 插件开发`](https://github.com/fuzhengwei/guide-idea-plugin) | [`Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践`](https://github.com/fuzhengwei/Lottery) | [`API网关`](https://github.com/fuzhengwei/api-gateway) | [`手写MyBatis`](https://github.com/fuzhengwei/small-mybatis) | [`重学Java设计模式`](https://github.com/fuzhengwei/itstack-demo-design) | [`Netty 实战案例`](https://github.com/fuzhengwei/itstack-demo-netty) | [`字节码编程`](https://github.com/fuzhengwei/itstack-demo-bytecode) | [`ChatGPT AI 问答助手`](https://github.com/fuzhengwei/chatbot-api) | [`chatglm-sdk-java`](https://github.com/fuzhengwei/chatglm-sdk-java) | [`docker-image-pusher`](https://github.com/fuzhengwei/docker-image-pusher) | [`💱IDEA Plugin vo2dto —— 对象转换插件(15.8k+安装)`](https://bugstack.cn/md/product/idea-plugin/vo2dto.html) | [更多搜索...](https://github.com/fuzhengwei?tab=repositories)
- :seedling: 干货：[公众号『 bugstack虫洞栈 』](https://bugstack.cn/images/personal/qrcode.png)
- :pencil: 博客：[bugstack.cn](https://bugstack.cn/) - 足够硬核，内容老狠了！
- :tv: 视频：[B站 小傅哥の码场](https://space.bilibili.com/15637440)
- :love_letter: 微信：[fustack](https://bugstack.cn/images/personal/fustack.png) - 备注来意
- :feet: 我的编程知识星球「码农会锁」：[实战生产级项目、手写框架级源码，可以向我 1对1 提问，解答技术/职场/规划问题](https://bugstack.cn/md/zsxq/introduce.html)

### 开发的项目

- 创新项目「AI」(13)
    - [AI Agent Guide - 通识教程](https://ai-agent-guide.xiaofuge.cn/) - `做AI项目前，可以先刷下。`
    - [WaLiSSH - AI Shell 智能终端](https://bugstack.cn/md/project/walissh/walissh.html)
    - [WaLiCode - AI Coding/DevOps 可持续交付助手](https://bugstack.cn/md/project/walicode/walicode.html) - `在 walissh 上扩展，代码已经提前提交`
    - [AI MCP Gateway 网关服务系统](https://bugstack.cn/md/project/ai-mcp-gateway/ai-mcp-gateway.html)
    - [AI Agent 脚手架 + 场景应用（draw.io、手机龙虾）](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html) - 综合 Spring AI、LangChain4j + Google ADK（a2a、mcp、skills），打造全新智能体架构方案。
    - [AI Agent 拖拉拽 + 动态配置（RAG、MCP、Prompt）](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html)
    - [OpenAI 代码自动评审组件](https://bugstack.cn/md/zsxq/project/openai-code-review.html)
    - [OpenAI 大模型微服务应用体系构建 - API-SDK、鉴权、公众号、微信支付](https://bugstack.cn/md/zsxq/project/chatgpt.html)
    - [ChatGPT AI 问答助手 - 小型，对接知识星球](https://bugstack.cn/md/zsxq/project/chatbot-api.html)
    - [AI 新范式（0编码），开发 + 运维（部署、压测、调优）](https://bugstack.cn/md/project/ai-new-paradigm/ai-new-paradigm.html)
    - [WaLiAPI - AI LLM LocalGateway 本地网关系统（渠道分发、日志留存、日志审计，知识库）](https://bugstack.cn/md/project/waliapi/waliapi.html)
    - [WaLiOffice - 在线办公系统（docx、ppt、draw.io、excel、图像、视频）](https://bugstack.cn/md/project/walioffice/walioffice.html)
    - [Java + DDD，1:1 复刻 Deepseek Harness 项目](https://bugstack.cn/md/project/deepseek-harness-java/deepseek-harness-java.html)

- 业务项目(5) 
    - [拼团交易平台系统](https://bugstack.cn/md/project/group-buy-market/group-buy-market.html)
    - [小型支付电商系统 - 一套项目2套架构开发（MVC+DDD）](https://bugstack.cn/md/project/s-pay-mall/s-pay-mall.html)
    - [大营销平台系统 - 前后端 + Dev-Ops 的全栈式综合编程实战DDD项目！](https://bugstack.cn/md/project/big-market/big-market.html)
    - [Lottery 分布式抽奖系统 - 基于领域驱动设计的四层架构实践](https://bugstack.cn/md/zsxq/project/lottery.html)
    - [Netty+JavaFx实战：仿桌面版微信聊天](https://bugstack.cn/md/zsxq/project/im.html)

- 组件项目(8)
    - [本地任务消息组件](https://bugstack.cn/md/project/local-task-message/local-task-message.html)
    - [通用技术组件 - 🔧扳手工程](https://bugstack.cn/md/zsxq/project/xfg-wrench.html)
    - [透视业务流程 - 监控系统](https://bugstack.cn/md/zsxq/project/business-behavior-monitor.html)
    - [动态线程池组件](https://bugstack.cn/md/zsxq/project/dynamic-thread-pool.html)
    - [蓝兔支付SDK设计和开发](https://bugstack.cn/md/zsxq/project/ltzf-sdk-java.html)
    - [API网关：中间件设计和实践](https://bugstack.cn/md/zsxq/project/api-gateway.html)
    - [SpringBoot Starter 中间件设计和开发](https://bugstack.cn/md/zsxq/project/springboot-starter.html)
    - [IDEA Plugin 开发手册](https://bugstack.cn/md/zsxq/booklet/idea-plugin.html)

### 我的出版物

- 2021年出版[《重学Java设计模式》](https://u.jd.com/4I2CXeO) —— 涵盖一线互联网众多真实案例；交易、营销、秒杀、规则引擎等场景
- 2023年出版[《手写MyBatis：渐进式源码实践》](https://u.jd.com/wssnicY) —— 从零手写源码级复杂项目，提升架构思维与设计逻辑。锻炼编码能力。

### 我的电子书

- [小傅哥的《Java 面经手册》](https://download.csdn.net/download/Yao__Shun__Yu/14932325) —— 全书共计 5 章 29 节，417页11.5万字，耗时 4 个月完成。涵盖数据结构、算法逻辑、并发编程、JVM以及简历和互联网大厂面试等内容。但此书并不是单纯的面试题，也不是内卷八股文。而是从一个单纯的和程序员有关的数学知识点开始，深入讲解 Java 的核心技术。并且每一章节都配有实践验证的源码，可以对照着一起撸才更有感觉！
- [小傅哥的《倚天村·图解数据结构》](https://drive.weixin.qq.com/s?k=ACMA4AfQABUm2EZtFm#/) —— 全书共计4章14节，215页4.2万字100+张图片，耗时3个月完成。涵盖4类14种数据结构，包括：链表、数组、队列、堆栈、哈希表、堆、字典树、二分搜索树、平衡二叉树、2-3树、红黑树、并查集、图、布隆过滤器。
- [小傅哥的《字节码编程》](https://drive.weixin.qq.com/s?k=ACMA4AfQABUJWQ0P92#/) —— 全书共计107页，11万7千字，20个章节涵盖三个字节码框架(ASM、Javassist、Byte-budy)和JavaAgent使用并附带整套案例源码！
- [小傅哥的《IDEA Plugin 开发手册》](https://download.csdn.net/download/Yao__Shun__Yu/77484299) —— 此开发手册，分为4章12节循序渐进的通过实践案例开发的方式，串联 IDEA Plugin 开发的各项常用技术点，为读者讲解如何开发一个 IDEA 插件。

### 面试必备

- [100道八股题考试测验](https://bugstack.cn/md/zsxq/material/exam.html) —— 考题范围：数据结构、算法、源码、设计模式、系统架构、中间件、网络通信、实战项目、扩展问题
- [面试题汇总](https://bugstack.cn/md/zsxq/material/interview.html)：汇总关于面试问题、简历编写、上岸总结、招聘信息等内容
- [简历模板](https://t.zsxq.com/19hxv0cgY)：你可以在学习掌握博客中的技术以及大厂项目，按照简历模板的格式，包装和调整成你需要的简历内容，提高面试通过率。

### 公众号 - 关注获得新通知

最新文章会首发公众号，强烈推荐读者伙伴关注一波！另外，在公众号：bugstack虫洞栈 回复 `1024` 可以下载更多资源内容。

<div align="center">
    <img src="https://bugstack.cn/images/system/resources-xiaofuge.png?raw=true" width="650px">
    <div style="font-size: 9px;">公众号：bugstack虫洞栈</div>
    <br/>
</div>

### 联系我 - 可加技术交流群

沉淀、分享、成长，让自己和他人都能有所收获！你也可以扫码添加本站作者小傅哥的微信（记得备注从博客来的）

<div align="center">
    <img src="https://bugstack.cn/images/personal/wx_little.png?raw=true" width="500">
    <div style="font-size: 9px;">提示：如果添加失败，可以先扫码图中的客服，也可以找到我</div>
    <br/>
</div>

---

把博客安装到手机桌面：iOS 用户可以通过 Safari 浏览器来保存 bugstack.cn 到应用到首页屏幕上。具体操作：在 Safari 浏览器中打开博客 https://bugstack.cn 点击`分享按钮`->`添加到主屏幕`即可。—— 随时随地，开启学习！

---

### Md Ai A2a (`docs/md/ai/a2a.md`)

---
title: a2a
lock: need
---

# A2A，实际跑起来是什么样？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=116247031185424&bvid=BV1QTwfzzEcu&cid=36776771626&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

chatgpt（22年）-> LLM 进阶（23年）->  MCP 协议（24年）-> Skils 技能（25年）-> A2A 标准（25年），这几年 AI 发展的非常迅速，定义了协议，开发了组件，发布了产品。每个阶段，都有非常牛皮的代表性的内容，车速非常快🚌，不知道在坐的各位有没有掉队。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-01.gif" width="150px">
</div>

针对这些 LLM 大模型的相关知识，小傅哥也分别提供了相关实战类项目，包括；**AI 问答助手（23年）**、**OpenAi(ChatGPT/ChatGLM) 微服务应用体系构（23年）**、**OpenAI 代码自动评审组件（24年）**、**AI Agent 智能体 - 拖拉拽（25年）**、**AI MCP Gateway 网关服务系统（25年）**、**AI Agent 脚手架 + 场景应用（26年）**，通过这些实战项目，实践各类标准协议和技术组件（spring ai、google adk...）的使用，以及提供非常出色的解决方案。

因为后续的 ai agent 智能体项目，还会涉及到 a2a 协议，所以先给大家做个相关技术的使用方便大家快速实践理解。

>🧧 文末提供了20个实战项目（6个AI、5个业务、8个组件、1套源码），以及各类编程技术小册等。欢迎一起加入学习。

## 一、A2A 是什么？

A2A (Agent2Agent) 协议是 Google于2025年4月推出、并由 Linux基金会托管的开源开放标准。它作为AI智能体之间的“通用语言”，旨在实现不同框架、不同厂商构建的智能体（Agent）间跨平台发现、通信与协作。

随后25年底，Google 发布了 [a2a adk](https://central.sonatype.com/artifact/com.google.adk/google-adk-a2a/0.4.0) 组件（迭代速度很快）。之后借助代理开发工具包 (Google ADK)，我们可以构建复杂的多代理系统，其中不同的代理需要使用代理对代理 (A2A) 协议进行协作和交互！本节提供了一个全面的指南，指导您构建强大的多代理系统，使代理能够安全高效地进行通信和协作。

框架：[https://google.github.io/adk-docs/a2a/](https://google.github.io/adk-docs/a2a/)

源码：[https://github.com/google/adk-java](https://github.com/google/adk-java)

资料：[https://www.ibm.com/cn-zh/think/topics/agent2agent-protocol](https://www.ibm.com/cn-zh/think/topics/agent2agent-protocol)

文档：[https://a2aprotocol.ai/docs/](https://a2aprotocol.ai/docs/)

---

如图，整套智能体架构（含A2A）；

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-02.png" width="950px">
</div>

- 左侧，是 LLM 模型智能体构建，基于 Spring AI 框架实现。这部分包括，AiApi 使用、RAG、MCP、Skills 的组合构建。
- 右侧，是 AI Agent 智能体编排，基于 Google ADK 框架实现。这套框架，提供了智能体工作流组装，插件回调钩子等各项基于 Google 发布的协议进行构建的。
- 之后，右上方，是 Google ADK 26年基于 A2A 协议实现的框架组件，方便我们设计出远程的 A2A 服务对接，把远程服务，转换为本地功能组件，编排进智能体中。因此 A2A 协议的作用，就是让一个远程的智能体，可以像构建本地智能体一样，连接起来进行使用。

> 基于 a2a  的协议，也有很多三方框架，但我们需要的是一个整体的解决方案，单一一个功能，还不能解决所有问题。所以这里优先选择 google adk 框架。

## 二、实践案例

### 1. 编程环境

- jdk 17
- google adk 0.8
- spring ai 1.1.0-M3

>相关的版本包，已经在测试工程中的 pom 里引入了。可以打开工程查看。

### 2. 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-02.png" width="550px">
</div>

- 工程：[https://github.com/fuzhengwei/xfg-dev-tech-google-adk-a2a-server](https://github.com/fuzhengwei/xfg-dev-tech-google-adk-a2a-server)
- 说明：基于 Google ADK 框架，构建 A2A 服务端和客户端。注意，服务端的启动方式为 `quarkus.sh` 方式启动服务，之后使用客户端连接。
- 注意：这部分还有一些关于关于 Spring AI + Google ADK 的基础使用知识，是在 ApiTest 中有案例。也可以学习项目 [《AI Agent 脚手架 + 场景应用》](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html)

### 3. 测试案例

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 这是一个 Spring AI + Google ADK 构建的简单智能体，由 LlmAgent 构建时候，创建模型 `new SpringAI(chatModel)` 关联到 Spring AI 框架。
- 之后，由 Google ADK 构建的智能体，使用内存记忆，创建会话之后进行测试。也可以学习项目 [《AI Agent 脚手架 + 场景应用》](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html) 锻炼使用相关内容。

### 4. A2A 测试

#### 4.1 服务端

这部分内容的学习，可以打开案例代码，方便对比。

##### 4.1.1 服务提供

```java
@ApplicationScoped
public class AgentExecutorProducer {

    @ConfigProperty(name = "my.adk.app.name", defaultValue = "default-app")
    String appName;

    @Produces
    public AgentExecutor agentExecutor() {
        return new com.google.adk.a2a.executor.AgentExecutor.Builder()
                .agent(Agent.ROOT_AGENT)
                .appName(appName)
                .sessionService(new InMemorySessionService())
                .artifactService(new InMemoryArtifactService())
                .agentExecutorConfig(AgentExecutorConfig.builder().build())
                .build();
    }
    
}
```

- 这部分是把智能体提供出去，通过 google adk 框架，创建 AgentExecutor 实例。
- 之后 Agent.ROOT_AGENT 类似于上面的测试案例，智能体构建的部分。你可以创建任何之后通过 AgentExecutor 发布出去。

##### 4.1.2 卡片提供

```java
@ApplicationScoped
public class AgentCardProducer {

    @Produces
    @PublicAgentCard
    public AgentCard agentCard() {
        try (InputStream is = getClass().getResourceAsStream("/agent/agent.json")) {
            if (is == null) {
                throw new RuntimeException("agent.json not found in resources");
            }

            // Read the JSON file content
            String json = new String(is.readAllBytes(), StandardCharsets.UTF_8);

            // Use the SDK's built-in mapper to convert JSON string to AgentCard record
            return Utils.OBJECT_MAPPER.readValue(json, AgentCard.class);

        } catch (Exception e) {
            throw new RuntimeException("Failed to load AgentCard from JSON", e);
        }
    }

}
```

**/agent/agent.json**

```java
{
  "capabilities": {"streaming": true},
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["application/json"],
  "description": "一个专门检查数字是否为素数的智能体。它可以高效地确定单个数字或数字列表的素性。",
  "name": "check_prime_agent",
  "skills": [
    {
      "id": "prime_checking",
      "name": "Prime Number Checking",
      "description": "使用高效的数学算法检查列表中的数字是否为素数",
      "tags": ["mathematical", "computation", "prime", "numbers"]
    }
  ],
  "preferredTransport": "JSONRPC",
  "url": "http://localhost:9090",
  "version": "1.0.0"
}

```

- 这里要构建一个智能体卡，A2A 的协议中，把服务包装成一个卡片的概念。
- agent.json 配置的是 `Agent.ROOT_AGENT` 智能体的信息。
- 如果你之前学习过小傅哥的 AI MCP 网关项目，会对 JSONRPC 有印象， MCP 协议和 A2A 协议，都是走到 JSONRPC 标准进行的通信。

#### 4.2 客户端

##### 4.2.1 构建端

```
/* Detailed source-code truncated for AI context efficiency. */
```

- createRootAgent 是构建入口，一个是创建 createRemoteAgent 远程智能体，一个是 `LlmAgent.builder()` 构建本地智能体。之后在构建本地智能体的时候，通过 subAgents 把远程智能体填充到本地的智能体里去了。这个编排的方式有多种多样的。
- createRemoteAgent 远程构建，这是固定协议路径 `/.well-known/agent-card.json`拿到智能体卡片以后（一个卡片上有各类的信息），之后通过 a2aClient 创建客户端，在通过 RemoteA2AAgent 完成本地智能体的转换。

##### 4.2.2 使用端

```java
public final class A2AAgentRun {
    private final String userId;
    private final String sessionId;
    private final Runner runner;

    public A2AAgentRun(BaseAgent agent) {
        this.userId = "test_user";
        String appName = "A2AAgentApp";
        this.sessionId = UUID.randomUUID().toString();

        InMemoryArtifactService artifactService = new InMemoryArtifactService();
        InMemorySessionService sessionService = new InMemorySessionService();
        this.runner =
                new Runner(agent, appName, artifactService, sessionService, /* memoryService= */ null);

        ConcurrentMap<String, Object> initialState = new ConcurrentHashMap<>();
        var unused =
                sessionService.createSession(appName, userId, initialState, sessionId).blockingGet();
    }
    
    // ... 省略部分

    public static void main(String[] args) throws InterruptedException {
        BaseAgent agent = A2AAgent.createRootAgent("http://localhost:9090");
        A2AAgentRun a2aRun = new A2AAgentRun(agent);

        List<Event> events =
                a2aRun.run("掷一个6面的骰子。").toList().timeout(90, TimeUnit.SECONDS).blockingGet();

        events.forEach(A2AAgentRun::printOutEvent);

        events =
                a2aRun.run("这是素数吗？").toList().timeout(90, TimeUnit.SECONDS).blockingGet();

        events.forEach(A2AAgentRun::printOutEvent);
    }

}
```

- A2AAgentRun 测试入口，连接远程的智能体，之后做相关的调用验证。

## 三、测试验证

### 1. 前置准备

1. IntelliJ IDEA 右侧的 maven 点击执行 clean -> install 构建
2. 通过命令启动服务，`mvn quarkus:dev -pl xfg-dev-tech-app`

### 2. 访问服务

#### 2.1 服务首页

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-03.png" width="650px">
</div>

- 地址：[http://localhost:9090/q/dev-ui/welcome](http://localhost:9090/q/dev-ui/welcome)
- 说明：访问首页，localhost:9090 会看到上面的地址信息，这个是 a2a 协议的入口。

#### 2.2 服务协议

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-04.png" width="650px">
</div>

- 地址：[http://localhost:9090/.well-known/agent-card.json](http://localhost:9090/.well-known/agent-card.json)
- 说明：点击 agent-card.json 可以看到具体的服务协议信息。

### 3. 调用验证

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-05.png" width="850px">
</div>

- 点击运行，你可以看到它在进行多个智能体的调用（可能模型原因不准，但核心点在于多个智能体的调用）。
- 好啦，到这关于 A2A 整个内容就演示完了，可以时刻关注 google adk a2a 协议的迭代，这部分内容后续还会有一些调整。

---

### Md Ai Agent Skill (`docs/md/ai/agent-skill.md`)

---
title: agent-skills
lock: need
---

# Agent Skill，你记一下，我做如下部署调整！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115890381129183&bvid=BV1PprJBeEmY&cid=35370763226&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

skill 是什么？它像是一本技能书📚，把一阳指（`mcp/py/shell/js`）和狮吼功（`prompt`）合成了一整招。缩短了从用户把提示词发给AI客户端，进行分析，决策，再到 mcp 执行的过程，**让诉求直达结果**，token 减少了，幻觉减少了！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-00.png" width="250px">
</div>

随着 LLM 大模型能力的不断提升，并与 RAG、MCP、Skill 的结合，使得 Agent 智能体与完整的计算机环境（Computer/Phone）交互成为可能。这个过程中，一方面不断产生新的技术方案，一方面又不断的优化设计。就像 Skill 的出现，它不是替代 MCP，而是更准确的使用 MCP 能力。

接下来，小傅哥就带着大家使用一波 skill，让小伙伴们可以在 opencode、trae.ai，以及基于 Spring AI 也可以使用上 skill 能力。

## 一、skill 和 prompt + mcp

如图，演示了一段 skill 的编写案例；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-02.png" width="850px">
</div>

- 场景：案例中体现的是，对电脑性能检测后，用一段下达命令的方式，告知用户如何优化电脑性能。
- 重点：如果不使用 skill，则需要描述一大段话术，让 ai 自己完成对用户场景诉求的分析，并按照步骤来调用对应的各个 mcp 服务（没有 skill 则需要把各类内容，都包装为 mcp 服务）。这个过程是比较消耗 token 的，也可能有不小的幻觉。现在有了 skill，我们可以适当的完整的写一段诉求文档，文档里嵌入可执行的脚本/mcp服务，让执行更可靠。
- 用途：那都有哪些场景可以写 skill 技能书呢？🤔 如；互联网公司里的系统巡检，在接收到报警日志后，拿到一个报警的系统和接口信息，之后用 skill 技能书，分别采集出对应的系统配置、上线日志、数据库/缓存情况、运营操作记录、全链路监控上的接口耗时情况等。之后在根据我们日常排查问题的时候经验，编写过程步骤，这样会更加准确。

> 所以，不是 skill、mcp 谁替代谁，而是 skill 对 mcp 进行增强，让 ai 执行时更加可靠。

## 二、配置使用

首先，像是市面上的 claude code、opencode 这些软件，都是支持了 skill 技能书配置使用的，如果遇到一些软件暂时还不支持 skill，或者自己使用 spring ai、langchain4j、google adk 构建的智能体时候需要使用 skil 技能，则可以通过 skillport-mcp 来使用 skill 配置。

这里小傅哥分别演示下 opencode、trae.ai + mcp、spring ai + google adk + mcp 的方式使用 skill；

### 1. 测试工程(skill)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-03.png" width="300px">
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-agent-skills](https://github.com/fuzhengwei/xfg-dev-tech-agent-skills)
- 说明：
  - 工程里 `docs/skills` 下面就是一个个技能书，battle-plan、pdf，每一个技能书下都必须有一个 SKILL.md 文件，作为入口。这个文件，可以描述 prompt 提示词，以及在提示词中明确给出可执行的脚本(py\shell\js)和可参考的文档。
  - 此外，在 xfg-dev-tech-app 下，test 里编码的是 SpringAiToolTest 测试技能书案例。

### 2. opencode 使用

- 文档：[https://opencode.ai/docs/skills/](https://opencode.ai/docs/skills/)
- 安装：[https://bugstack.cn/md/road-map/ai-ssh-opencode.html](https://bugstack.cn/md/road-map/ai-ssh-opencode.html) - `做好了安装脚本，方便小白伙伴使用`

#### 2.1 配置skill

```java
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % ls
battle-plan
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % pwd
/Users/fuzhengwei/.opencode/skill
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % cd battle-plan 
fuzhengwei@fuzhengweideMacBook-Pro-2 battle-plan % ls
reference.md	scripts		SKILL.md
fuzhengwei@fuzhengweideMacBook-Pro-2 battle-plan % 
```

进入到 opencode 配置文件下，如果是 linux 一般会放到 `/root/.config/opencode/` 下。首先你要进入到这个 opencode 配置文件夹，之后在这个文件夹添加一个 skill，再之后就在 skill 下创建你的具体的技能书了。现在你可以把 xfg-dev-tech-agent-skills 案例工程的技能书，battle-plan 放到 skill 里。

#### 2.2 开启skill

```java
fuzhengwei@fuzhengweideMacBook-Pro-2 ~ % cd /Users/fuzhengwei/.opencode
fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % ls
bin		node_modules	package.json
bun.lock	opencode.json	skill
fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % cat opencode.json 
{
  "permission": {
    "skill": {
      "pr-review": "allow",
      "internal-*": "deny",
      "experimental-*": "ask",
      "*": "allow"
    }
  },
  "$schema": "https://opencode.ai/config.json"
}%                                                                                            fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % 
```

- 注意 `opencode.json` 需要配置下 `"*": "allow"`

#### 2.3 使用skill

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-04.png" width="600px">
</div>

- 提问：`基于 skill 解答，电脑性能优化`
- 说明：这里的`电脑性能优化`就是 skill 工具名称的描述。

### 3. trae.ai + mcp + skill

#### 3.1 工具说明

工具：[https://github.com/gotalab/skillport](https://github.com/gotalab/skillport)

目前还有不少 AI Agent 智能体，在底层设计上，还不支持直接使用 skill，也包括一些 ai 组件框架，也都没有 skill 的直接支持。那么这里要引入一个 skillport-mcp 服务来解决。借助 mcp 能力，使用 skill。

#### 3.2 工具安装

```java
# 需要安装 python3
pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple/
pip3 install uvx
```

- 安装 skillport 前，要确保本地安装了 pyhton/python3 环境。之后有 uvx 的安装。

```java
pip3 install skillport
# or: uv tool install skillport
```

- 如果安装过程中遇到一些失败的问题，可以用 trae.ai 里面执行安装，之后把报错拖进去提问。

#### 3.3 mcp 配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-05.png" width="600px">
</div>

```java
{
  "mcpServers": {
    "skillport": {
      "command": "uvx",
      "args": ["skillport-mcp"],
      "env": { "SKILLPORT_SKILLS_DIR": "~/.skillport/skills" }
    }
  }
}
```

- 这里你要配置下自己 skill mcp 服务，到你的 trae.ai 中。确保一定安装好了 python 环境，可以执行 `pip3 install skillport` 安装。

#### 3.4 工具使用

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-01.png" width="400px">
</div>

当你选择 Builder with MCP（涵盖了skillport-mcp），之后提问 `基于 skill 解答，电脑性能优化` 那么就可以得到上面的命令了。

### 4. spring ai + skill

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 在 Spring AI 程序中，添加 `skillport-mcp` 服务，之后在 ChatModel 模型里，使用 mcp 服务。
- 如果你正在开发一些 AI Agent，那么也可以把 `skillport-mcp`  配置进去使用。如小傅哥带着做 [AI Agent 智能体项目](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 你现在可以加进去更多的扩展操作了。

---

### Md Ai Ai Agent Guide Wx (`docs/md/ai/ai-agent-guide-wx.md`)

---
title: AI Agent Guide 小程序版
lock: need
---

# AI Agent Guide 小程序版

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

`傅哥，我想手机也能看`、`傅哥，我要车上直接听`、`傅哥，我许愿语音辅助背题` ...，做，都做。做你的，做完你的做你的。**刚上线，都2000+用户啦！** 还有几个熬夜，直接背题的！说上头了！🤯

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-01.gif" width="150px">
</div>

**都放假了，这是整的啥东西？**

这是你的大厂 offer！

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-02.png" width="150px">
</div>

这个你知道，我知道，你就不用问了。自然有人会先来用。你想了解什么，可以上手体验，也可以语音`听课`/`背题`。你们想要以偷懒、耍滑、侥幸，那 `10.1` 后的面试，别哭着说没早点上手。

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-03.png" width="850px">
</div>

这真是，哇哇干呀！伙伴们，跟着小傅哥不会错的！

**AI Agent 通识教程**，小傅哥做过一个 Web 网页版，[https://ai-agent-guide.xiaofuge.cn](https://ai-agent-guide.xiaofuge.cn/) 到目前已有非常多的伙伴，通过这套教程理解关于智能体的设计到实现的方案和技巧。在面试中，解答各类问题，也都非常顺畅。`（这样的基础教程都是免费的）`

那这会，大家不都放假了吗。路上啊，坐车啊，在家啊，还想随时随地学习，咋办。抱着电脑也不方便，车上看东西还晃悠晕车。所以，趁着这几天时间，小傅哥给大家提供了这套教程的小程序版本。不只是能看，还能面试，又能语音听（一章章朗读，一个个解析）。

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-04.png" width="650px">
</div>

> 来吧，死鬼！这是不是你最期待的东西！接下来，小傅哥再简单介绍下`小程序版本`这套东西，方便你学习使用。

## 一、产品功能

**AI Agent 通识教程**，短期帮你提高面试能力，长期教你如何构建智能体。因为这些东西，都来自于真实的项目实战后，做的提炼总结。学习起来会真实感受到这些东西怎么做，而不会有空洞感。

就像；`上下文怎么裁剪`、`工具怎么调准`、`ReAct 何时跑何时停`、`记忆到底存什么`、`消息结构怎么设计才命中缓存`。干过智能体的面试官，几句从实际场景出发的问题，就能把小白问住。所以，如果你是希望充实 AI Agent 开发的伙伴，那么这套教程非常有必要刷一下。

### 1. 📚 课程内容

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-05.png" width="650px">
</div>

- 完整 Agent 知识体系：大模型基础 → 提示词/上下文工程 → ReAct → 记忆系统 → Function Calling / MCP / Skills → RAG → 多 Agent 与 A2A → LangGraph → 评估安全部署，一站式学完
- 有白色/黑色主题，可以朗读内容、调整字体。核心概念配流程图解，不用啃大段文字，还可以把你需要的重点，长按收藏为段落笔记。

### 2. 🎯 面试考察

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-06.png" width="850px">
</div>

- **逐章面试**：30 章教程题库共 508 道题，按章检验掌握度，支持通关进度与正确率统计
- **4 种面试官风格**：🔥 犀利施压（还原大厂压力面）、🌸 温柔引导（适合初学者）、💼 大厂实战（只聊能上线的方案）、📐 稳重基础（抠概念准确性）
- **大厂真题**：字节跳动、美团、京东真题各 10 道，还原真实面试官提问节奏
- **混合面试**：多章随机抽题，模拟综合面
- **🎧 语音讲解**：老师念题 + 同学讲解，支持续听，通勤路上戴耳机就能刷面试题

### 3. 🪜 学习排行

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-07.png" width="850px">
</div>

- **云端笔记**：阅读时**长按任意段落**即可收藏或写笔记，云端同步、支持复制/编辑/删除，重点句和心得一起沉淀
- **学习排行榜**：与所有学习者比拼学习时长，查看自己的排名
- **分享海报**：一键生成专属学习海报，发朋友圈晒进度

## 二、实战项目

随着对 AI Agent 的理解加深，加下来就是项目实战了。

AI Agent 通识教程，来自于实战项目的提炼。这里小傅哥也为大家准备了完整的实战项目；你可以刷到 AI 八股，也可以学会 AI VibeCoding 编程，还能实践各类 AI 项目。如，市面的 AI IDE（walissh、walicode）教你做一套市面上的 trae.ai/qcoder 一样的编程工具。WaLiAPI（LLM 负载、日志审计、RAG 知识库）、AI MCP Gateway 教你如何构建 AI Infra 基础设施。还有 DSH Java，快速对接业务场景，也能做出 XxxBuddy 类产品。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-10.png" width="850px">
</div>
综上，路线总图，表面看是项目。其实我是带着你做方案；

1. 最上面是基础的 AI 认知和 VibeCoding 入门，紧接着是非 Agent 的 AI 实战，如；OpenAI 代码自动评审、OpenAI 应用。紧接着是 Agent 基础设施 WaLiAPI（LLM Gateway）、AI MCP Gateway
2. 紧接着是3套技术架构方案，第一套拖拉拽类似 Dify 的简单版，做个 Agent 入门，了解关于 Agent 基础设计。之后是脚手架方案，通过 Spring AI、Google ADK 封装通用脚手架组件，之后来实现不同类型场景的项目。有脚手架可以快速开发。现在正在搞的是 Harness 马具插件方案，也就是说，提供一套核心 Agent 运行时，之后其他场景的对接，只是插件的开发实现。对接业务类场景效率非常高。
3. 右侧，是业务类 toc 项目，以及 API Gateway 网关场景。当你做的多了就会知道，即使做 Agent 你也离不开业务技术的储备。

> 好啦，欢迎👏🏻小伙伴跟着小傅哥，一起深度积累自己的编程技术。在一些时候，不知道往哪走的路口上，有个参考。

---

### Md Ai Ai Agent Guide (`docs/md/ai/ai-agent-guide.md`)

---
title: AI Agent 八股文小册
lock: need
---

# AI Agent 八股文

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

`Agent 架构与传统 LLM 链式调用有什么区别？` `什么是 ReAct 模式，底层工作原理是什么？` `多轮 Agent 对话怎么解决上下文溢出？` `Agent 工具调用的工具类型都有哪些，在长对话中，怎么保证 Agent 的工具调用的可靠性。` 哈，**死鬼**，想转 Agent 应用开发工程师吗，这些问题你准备好了吗，有过项目实践吗？

<div align="center">
	<img src="https://bugstack.cn/images/article/project/walicode/walicode-introduce-01.gif" width="150px"/>
</div>

在此之前，小傅哥，从22年尾就一直跟进 AI 方向，先后做；AI 问答助手、OpenAI 大模型应用、OpenAI 代码自动评审、AI MCP Gateway，基础的做完就开始搞 AI Agent 智能体系列（拖拉拽、脚手架），AI + Draw.io、AI + Moblie，紧接着推出重型项目 `WaLiSSH`、`WaLiCode` 全面推进！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-10.png" width="650px"/>
</div>

**可以这么讲，跟着小傅哥，哪有掉队的可能。** 你还得走到头部呢，而且有这么多 AI Agent 应该应用开发岗位，简直就是这个时代的机会！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/walicode/walicode-introduce-02.png" width="450px"/>
</div>

是个机会，但这个东西吧！整体来讲呢，`AI Agent 应用开发`不算难。不过很多伙伴，并不是一开始就跟着 AI 的，而是 AI 知识都爆发成这样了，才后知后觉。所以，一下子懵😳了，不知道从哪开始学了。

`不过，别着急。小傅哥，再拉你一把！`

[《AI Agent Guide》](https://ai-agent-guide.xiaofuge.cn/) 来啦，从基础认知到面试通关 · 21章渐进式可视化教程。官网：[https://ai-agent-guide.xiaofuge.cn/](https://ai-agent-guide.xiaofuge.cn/)

这是小傅哥基于现在开发的 AI Agent 项目（[WaLiCode](https://walicode.xiaofuge.cn/)），提炼出来的一套智能体入门和面试教程。还附带着免费的 AI 对话，辅助学习。

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-01.png" width="950px"/>
</div>

这是一套**从零到面试通关**的 AI Agent Guide 宝典，用可视化动画拆解复杂概念，循序渐进的由浅入深的帮助大家理解和掌握 Agent 智能体。并且每节内容，都覆盖了核心内容的讲解，八股文章的总结和课后面试问题的考察。除此之外，还附带了 AI 工具（免费的）帮助大家理解和学习整套课程。可以说这套教程，是当下最系统的中文 AI Agent 学习资源之一。

>接下来，小傅哥就详细的介绍下 ai-agent-guide 教程，方便大家知道都可以学习到啥。

## 一、教程能学到啥？

这套教程一共 21 章，小傅哥给大家分成了 6 大篇章，从零基础到面试通关，一步步来。

### 第一篇：Agent 基础认知（第0-5章）

> 🎯 目标：搞懂 AI Agent 是啥，为什么需要它，和 Chatbot 有啥区别。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第0章 | Agent 能力全景展示 | Token、Prompt、Embedding 全景认知，建立整体概念 |
| 第1章 | 大模型与 Agent 基础概念 | LLM 原理、Token 机制、Prompt Engineering 怎么写 |
| 第2章 | 什么是 AI Agent？ | Agent 定义、架构、与 Chatbot 的本质区别 |
| 第3章 | 你的第一个 Agent：天气查询 | 从零构建 Agent，Function Calling 实战 |
| 第4章 | ReAct：让 Agent 学会思考 | Reasoning + Acting 循环，思维链拆解 |
| 第5章 | Agent 的记忆系统 | 短期/长期记忆、向量检索、记忆管理 |

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-02.png" width="750px"/>
</div>

**💡 这一篇是入门关键**，很多伙伴卡在"Agent 到底是啥"这个问题上。小傅哥用可视化动画，把抽象概念具象化，看完你就能跟面试官掰扯明白了。

### 第二篇：工具与技能（第6-9章）

> 🛠️ 目标：让 Agent 拥有"手"和"脑"，能调用工具、组合技能。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第6章 | Function Calling 与工具设计 | 工具协议、参数 Schema、最佳实践 |
| 第7章 | MCP：工具的标准化接口 | Model Context Protocol、Server/Client 架构 |
| 第8章 | Skills：工具的组合与复用 | 技能编排、Prompt 模板、组合调用 |
| 第9章 | CLI 能力：Agent 操作本地工具 | Shell 执行、文件操作、系统交互 |

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-03.png" width="750px"/>
</div>

**💡 这一篇是实战核心**，Agent 光会聊天没用，得能干活。从 Function Calling 到 MCP 协议，再到 Skills 技能组合，最后到 CLI 命令行操作，层层递进，让你的 Agent 真正成为"数字员工"。

### 第三篇：多 Agent 协作（第10-11章）

> 🤝 目标：从单 Agent 到多 Agent 系统，理解协作模式和编排机制。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第10章 | 多 Agent 系统架构 | 协作模式、通信机制、分工策略 |
| 第11章 | LangGraph 与状态机 | 图编排、状态流转、条件分支 |

**💡 这一篇是进阶内容**，单兵作战已经不够了，现实场景都是团队协作。多 Agent 协作、LangGraph 状态机编排，这些是工业级 Agent 系统的必备知识。

### 第四篇：框架与平台（第12-13章）

> 🏗️ 目标：了解主流 Agent 框架和低代码平台，知道怎么选、怎么用。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第12章 | 主流 Agent 框架对比 | LangChain / CrewAI / AutoGen 横评 |
| 第13章 | Dify、Coze 与可视化编排 | 低代码平台、工作流设计、插件生态 |

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-04.png" width="750px"/>
</div>

**💡 这一篇是选型指南**，市面上框架这么多，到底选哪个？小傅哥帮你横向对比，再结合 Dify、Coze 这类低代码平台，让你知道什么时候该写代码、什么时候该拖拽。

### 第五篇：实战场景（第14-16章）

> 🚀 目标：CLI Agent、GUI Agent、RAG 三大实战场景全覆盖。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第14章 | CLI Agent：命令行智能助手 | 终端 Agent 实战、代码生成、运维自动化 |
| 第15章 | GUI Agent：浏览器自动化 | 网页操作、表单填写、截图理解 |
| 第16章 | RAG：检索增强生成 | 文档切分、向量化、检索策略 |

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-05.png" width="750px"/>
</div>

**💡 这一篇是落地实操**，学完就能用在项目里。CLI Agent 帮你自动运维，GUI Agent 帮你自动填表，RAG 帮你做知识库问答。这些都是当下企业最需要的 Agent 应用场景。

### 第六篇：工程化与展望（第17-21章）

> ⚙️ 目标：Agent 的评估、安全、部署，以及未来趋势展望。

| 章节 | 标题 | 学完你会 |
|------|------|----------|
| 第17章 | Agent 评估与可观测性 | 评测指标、Trace 追踪、LangSmith |
| 第18章 | Agent 安全与防护 | Prompt 注入、权限控制、沙箱隔离 |
| 第19章 | Agent 部署与运维 | 容器化、弹性伸缩、监控告警 |
| 第20章 | 推理框架与模型服务化 | Ollama、vLLM、Spring AI 部署实践 |
| 第21章 | 2026 Agent 技术展望 | 多模态、具身智能、Agent 生态趋势 |

**💡 这一篇是收官之作**，从工程化角度保障 Agent 的稳定运行，最后展望未来，让你知道 AI Agent 的未来在哪，提前布局。

## 二、教程有啥特色？

### 1. 可视化动画，概念秒懂

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-06.png" width="750px"/>
</div>

很多教程讲 ReAct、MCP 这些概念，上来就是一堆文字和代码，看半天不知所云。

小傅哥的教程不一样，**每章都有自研的 SVG 流程图引擎**，把抽象概念画成动画。比如 ReAct 的 Reasoning + Acting 循环，你看一遍动画就记住了，比看十遍文字都管用。

### 2. 每章三板斧：文章 + 八股 + 考试

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-07.png" width="450px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-08.png" width="450px"/>
</div>


每章内容，小傅哥给你拆成三个部分：

- 📖 **文章**：章节正文，动画流程图 + 代码示例，循序渐进
- 📋 **八股**：面试高频考点精炼总结，面试官视角点评，考前必看
- 📝 **考试**：课后考试题，5 道单选 + 3 道多选，自动判分，错题收录

学完一章，考一下，知道自己掌握没。130+ 道面试题，模拟真实面试场景。

### 3. 内置 AI 助教，边学边问

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/ai-agent-guide-09.png" width="350px"/>
</div>

遇到不懂的？右边直接问 AI 助教！我都帮你做好了匹配这套教程的轻量智能体。

- **开箱即用**：内置免费 API，不用额外配置
- **上下文感知**：AI 知道你正在学哪章，回答更精准
- **多模型支持**：GPT / Claude / Gemini / 国产模型都能配
- **流式响应**：打字机效果，实时显示

## 三、配套工具：让学习更轻松

光有教程还不够，小傅哥还给你准备了实战项目，让你的学习事半功倍。**WaLiCode：AI 编码助手**

<div align="center">
	<img src="https://bugstack.cn/images/article/project/walicode/walicode-introduce-05.png" width="750px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/project/walicode/walicode-introduce-11.png" width="750px"/>
</div>

[WaLiCode](https://walicode.xiaofuge.cn/) 是小傅哥自研的 AI 编码助手，这套教程就是基于 WaLiCode 开发的。

- **Skills 技能支持**：安装各种技能包，扩展 AI 能力
- **SSH 远程操作**：直接连接服务器，部署、调试一条龙
- **MCP 协议支持**：连接各种工具和服务
- **多模型切换**：支持多个 LLM 提供商

学教程的过程中，配合 WaLiCode 实践，效果更佳！课程：[https://t.zsxq.com/s83De](https://t.zsxq.com/s83De)

## 四、怎么学最高效？

小傅哥给你规划了一条**最高效的学习路径**：

### 1. 零基础入门（推荐新手）

```
第0章 → 第1章 → 第2章 → 第3章 → 第4章 → 第5章
  ↓         ↓         ↓         ↓         ↓
 建立认知   懂LLM    懂Agent   动手做    懂ReAct  懂记忆
```

**耗时**：约 1 周

这一条路径，适合完全没有 AI Agent 经验的伙伴。按顺序学完前五章，你就能理解 Agent 的基本原理，并且亲手写出你的第一个天气查询 Agent。

### 2. 实战进阶（有基础推荐）

```
第6章 → 第7章 → 第8章 → 第9章 → 第10章 → 第11章
  ↓         ↓         ↓         ↓         ↓         ↓
 工具调用   MCP协议   技能编排   CLI操作   多Agent   状态机
```

**耗时**：约 1.5 周

这条路径适合已经了解 Agent 基础的伙伴，重点攻克工具调用、多 Agent 协作、LangGraph 编排等核心技术。

### 3. 面试突击（求职推荐）

```
全章快速过 → 重点看八股 → 做考试 → 查漏补缺
```

**耗时**：约 3 天

每条路径最后，别忘了做每章的考试！130+ 道面试题，覆盖所有核心考点。面试前刷一遍，心里有底。

---****

---

### Md Ai Ai Llm (`docs/md/ai/ai-llm.md`)

---
title: 什么？AI != 百度搜索，AI 是文字接龙？
lock: need
---

# 什么？AI != 百度搜索，AI 是文字接龙？


作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

你以为 AI 像是百度搜索一样的，更准的内容检索吗？但恰恰相反，AI 是一点也不会检索，而是文字接龙，从一个字/词（token）预测下一个字/词（token）。那凭直觉预测（温度），AI 不得是个大傻子？咋那么准呢？

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-llm-01.png" width="150px">
</div>

**如果一开始就知道，这货就是在组词呢，我也担心准确率！**

单凭随机预判的创作逻辑，听着是不是觉得 AI 笨得离谱？可现实里它既能流畅对话、梳理逻辑，还能写文编程、解答难题，精准度远超大家想象。

这份反差感恰恰是大模型最有意思的奥秘。看似毫无思考逻辑的逐词推演，叠加海量数据沉淀、语义编码、注意力联动层层机制，硬生生拼凑出堪比人脑的智慧表现。接下来咱们抛开晦涩公式，顺着技术发展脉络，一层层扒开 AI 聪明又时常犯傻的底层真相。

> 💐掌握本质，实战项目，积累经验，储备能力。就永远也不会被甩下车！

## 引子：先建立一个核心比喻

整篇文章我都会围绕一个比喻展开：

> **AI 大模型 = 一个读完了整个互联网，但完全没有人生经历的"超级文字接龙选手"。**

记住这句话。后面所有概念，都是在这个比喻基础上一层层加细节。

```mermaid
graph LR
    A[整个互联网的文字] --> B[喂给一个超大的神经网络]
    B --> C["学会一件事: 预测下一个字"]
    C --> D["就成了你看到的 AI"]
```

---

## 一、AI 的"前世今生"——一部充满故事的编年史

在我们拆解技术之前，先讲讲 AI 是怎么一步步走到今天的。这段历史不仅有意思，而且**每个转折都对应着今天 AI 的一个能力或局限**。读完你会发现：原来 ChatGPT 不是凭空出现的，它身上每一块拼图都有自己的故事。

### 0.1 史前时代（1950s - 2000s）：AI 的两次"寒冬"

```mermaid
graph LR
    A["1956 达特茅斯会议 'AI'一词诞生"] --> B["1970s 第一次寒冬 规则系统撞墙"]
    B --> C["1980s 专家系统复兴"]
    C --> D["1990s 第二次寒冬 'AI 是骗子'"]
    D --> E["2006 深度学习苗头"]
```

**1956 年夏天，达特茅斯学院**。一群年轻科学家（其中包括后来图灵奖得主 McCarthy、Minsky）开了一个为期两个月的研讨会。会议宣言里第一次出现了 "**Artificial Intelligence**" 这个词。他们当时乐观地认为：**再过 10 年，机器就能像人一样思考。**

结果呢？他们错了——错得很离谱。

接下来 50 年里，AI 经历了两次"寒冬"。每次都是科学家承诺得太多、做不到、政府断了经费、行业崩盘。中间出现过一些有意思的尝试：

- **专家系统**：靠人手工写几万条规则，让计算机模拟医生诊断、律师答疑。结果发现规则越加越多，越来越乱，根本扩展不动。
- **统计 NLP**：放弃规则，改用数学统计。能做翻译，但翻得磕磕巴巴。

> 💡 **关键启示**：人类花了 50 年才明白一件事——**"教"机器是教不会的，得让机器"自己学"**。这就为后来的深度学习埋下了种子。

### 0.2 深度学习的觉醒（2006 - 2012）：三个"叛逆者"的坚持

整个 90 年代，神经网络是一个**被主流抛弃**的方向。当时学术界普遍认为"神经网络又慢又难训、永远做不出有用的东西"。

但有三个人**就是不信邪**：

```mermaid
graph TB
    A["Geoffrey Hinton 多伦多大学"] --> D["2006 年提出深度信念网络 证明深层网络可以训练"]
    B["Yann LeCun 纽约大学"] --> E["1998 年发明 CNN 用于识别手写数字"]
    C["Yoshua Bengio 蒙特利尔大学"] --> F["2003 年用神经网络做语言模型 Word Embedding 的雏形"]
    D --> G["2012 年 AlexNet 横空出世 把图像识别错误率 从 26% 直接砍到 16%"]
    E --> G
    F --> G
```

**2012 年是 AI 的"创世纪"年份**。Hinton 的学生 Alex Krizhevsky 用 GPU 训练了一个深度神经网络（AlexNet），在 ImageNet 图像识别比赛中把第二名甩开了 10 个百分点。

这一战的意义在于——**所有人突然意识到：GPU + 大数据 + 深层网络，原来真的可以工作！**

那三位"叛逆者"，2018 年共同拿了**图灵奖**（计算机界的诺贝尔奖）。坚持了 30 年的冷板凳，终于热了。

> 💡 **关键启示**：今天所有 AI 的算力基础是 **NVIDIA 的 GPU**。这家公司原本是做游戏显卡的，从来没想过会成为 AI 时代的卖水人。老黄（黄仁勋）现在是世界级首富——而这一切的起点，就是 2012 年 AlexNet 选择用 GPU 训练。

### 1.3 RNN 的崛起与困境（2013 - 2016）：长文本的"金鱼记忆"

深度学习在图像上爆发后，自然语言处理（NLP）也跟着进入了**深度学习时代**。当时的主角是 **RNN（循环神经网络）** 和它的升级版 **LSTM**。

它们的思路是：处理一句话时，一个词一个词地读，每读一个就更新一下"记忆"。

```mermaid
graph LR
    A[词1] --> H1[记忆状态1]
    B[词2] --> H2[记忆状态2]
    C[词3] --> H3[记忆状态3]
    D[词4] --> H4[记忆状态4]
    H1 --> H2 --> H3 --> H4
```

听起来很合理，对吧？但 RNN 有**两个致命缺陷**：

**缺陷一：金鱼记忆**

句子稍微一长，前面的信息就忘了。比如：

> "小明小时候在云南长大，跟爷爷奶奶一起生活了十几年，吃米线、过泼水节，所以他的母语是____。"

RNN 处理到最后那个空时，前面"云南"的信息几乎已经忘光了，它猜不出"傣语"或"普通话"。

**缺陷二：必须按顺序处理，没法并行**

RNN 必须先读完第 1 个词，才能读第 2 个；读完第 2 个，才能读第 3 个……

```mermaid
graph LR
    A[词1] --> B[词2] --> C[词3] --> D[词4] --> E[词5]
```

这意味着——**你买再多 GPU 也没用**，因为它们只能干等着。RNN 的训练速度被卡死了。

整个 2013-2016 年，NLP 学术界都在拼命改进 RNN，发明了 LSTM、GRU、双向 RNN、注意力机制（早期版本）……**就是治不好这两个病**。

> 💡 **关键启示**：技术的突破往往不是改良，而是**换一种思路**。RNN 走到了死胡同——救它的不是更聪明的 RNN，而是**把 RNN 整个扔掉**的新架构。

### 1.4 2017 年的"圣经时刻"：Transformer 横空出世

**2017 年 6 月 12 日**，Google 的 8 位研究员（Vaswani、Shazeer、Parmar 等）在 arXiv 上贴了一篇论文:

> **《Attention is All You Need》（你只需要注意力）**

这个标题狂得可以——他们直接说：**之前所有的 RNN、LSTM 都不需要了。只用一个叫"注意力"的机制，就够了。**

```mermaid
graph TB
    A["2017 前: RNN 时代 串行、健忘、慢"] --> B["2017.6 Transformer 论文"]
    B --> C["完全并行处理"]
    B --> D["一次看全篇"]
    B --> E["训练速度提升数十倍"]
    C --> F["2018 GPT-1 1.17 亿参数"]
    D --> F
    E --> F
    F --> G["2019 GPT-2 15 亿参数 OpenAI 一度不敢发布"]
    G --> H["2020 GPT-3 1750 亿参数 震惊世界"]
```

这篇论文有几个**戏剧性的小故事**：

- **8 个作者后来全部离开了 Google**。其中 Noam Shazeer 创办了 Character.AI（2024 年 8 月，Google 用约 27 亿美元的授权交易，把他和团队请回 Google 共同领导 Gemini 项目）；Aidan Gomez 创办了 Cohere（估值已超数十亿美元）；Łukasz Kaiser 去了 OpenAI，参与了 GPT-4 与 o1/o3 的核心研发。**"Transformer 八子"几乎组成了硅谷 AI 圈最贵的同学录**。

- **Google 自己反而错过了大模型时代**。它发明了 Transformer，但因为搜索业务太赚钱、又怕新产品冲击老业务，迟迟没有大规模押注。结果让一个名不见经传的小公司——**OpenAI**——抢了先。

- **论文标题来自一首披头士的歌**：《All You Need Is Love》。作者 Llion Jones 后来回忆，取这个名字"花了五秒钟"，他当时根本没想到大家真会用——结果它成了 AI 史上最著名的论文之一。

### 1.5 OpenAI 的豪赌（2018 - 2022）：把 Transformer 做大

Transformer 出来之后，大部分研究者还在拿它做小规模实验。但**有一家公司决定走极端路线**——这家公司就是 **OpenAI**。

它的思路简单粗暴：

> **Transformer 既然好用，那就把它**做大、做大、再做大。

```mermaid
graph LR
    A["GPT-1 2018 1.17 亿参数"] --> B["GPT-2 2019 15 亿参数"]
    B --> C["GPT-3 2020 1750 亿参数"]
    C --> D["ChatGPT 2022.11 5 天破百万用户"]
    D --> E["GPT-4 2023 多模态"]
```

每一代都有戏剧性的事件：

- **GPT-2（2019）**：OpenAI 训完后**吓得不敢全开源**，担心被用来生成假新闻。这一举动在学术界引起轩然大波，被批评"违背开源精神"。但后来事实证明，他们的担心**完全不是多余**——AI 生成内容的滥用问题在 2023 年后真的全面爆发。这东西我带着大家部署过，像个傻狗。[【部署教程】基于GPT2训练了一个傻狗机器人](https://bugstack.cn/md/algorithm/model/2023-02-12-chat-gpt.html)

- **GPT-3（2020）**：1750 亿参数，训练成本业界估算约 **460 万到 1200 万美元**。当时业内很多人质疑："堆参数有意义吗？" 结果 GPT-3 一发布，能写诗、能编程、能模仿任何人的口吻——所有质疑瞬间消失。

- **ChatGPT（2022.11）**：OpenAI 内部其实只是想"小试一下"，把 GPT-3.5 包了个聊天界面，**没人觉得它会火**。结果上线 5 天破 100 万用户，2 个月破 1 亿——成为人类历史上**用户增长最快的产品**（连 TikTok、Instagram 都没这么快）。微软 CEO 纳德拉看到数据后说了一句话："我们要让 Google 跳舞（dance）。"

> 💡 **关键启示**：很多人以为 ChatGPT 是个"突然出现"的产品。其实它是一条**长达 5 年的押注**：OpenAI 从 2018 年就开始押 Transformer + 大规模 + 自回归这条路。**那些看起来一夜爆红的东西，背后都有人在冷板凳上坐了五年十年**。

### 1.6 中国 AI 的奋起直追（2023 - 2025）：从跟跑到部分领跑

ChatGPT 火了之后，中国整个科技圈被打了个措手不及。但中国速度起来后，追赶的速度也惊人。

```mermaid
graph TB
    A["2023 ChatGPT 冲击波"]
    A --> B["百度文心一言 第一个国产对标产品"]
    A --> C[阿里通义千问]
    A --> D[字节豆包]
    A --> E[腾讯混元]
    A --> F["月之暗面 Kimi 长上下文先驱"]
    A --> G["智谱 GLM"]
    A --> H["DeepSeek 2024 末杀出黑马"]
    H --> I["2025 DeepSeek-R1 用 1/10 成本逼平 OpenAI o1 震动全球资本市场"]
```

特别值得讲的是 **DeepSeek**：

- 它是一家**杭州的对冲基金（幻方量化）孵化出来的 AI 公司**，没什么明星光环。
- 2024 年 12 月发布 DeepSeek-V3，**V3 的预训练成本约 557 万美元**（基于 2048 张 H800 GPU、约 278 万 GPU 小时），仅为同级别模型的几分之一。
- 2025 年 1 月 20 日发布 DeepSeek-R1（基于 V3 加强化学习训练），**推理能力对标 OpenAI 当时最强的 o1**，**而且完全开源**。
- 这条消息直接引爆全球资本市场：**2025 年 1 月 27 日，NVIDIA 股价单日暴跌约 17%，市值蒸发近 5890 亿美元**——创下美股历史上单只股票单日市值蒸发的新纪录，登上全球财经头条。

中国 AI 从 2023 年的"对标 ChatGPT"，到 2025 年的"在某些方向反过来定义标准"，只用了**两年**。这在科技史上极其罕见。

> 💡 **关键启示**：AI 不是"谁有钱谁赢"的游戏。**算法创新、工程优化、开源共建**，三样东西配齐，小团队也能掀翻巨头。

### 1.7 把历史浓缩成一句话

```mermaid
graph LR
    A["1956 AI 诞生"] --> B["1986-2006 神经网络冷板凳"]
    B --> C["2012 AlexNet 觉醒"]
    C --> D["2017 Transformer 革命"]
    D --> E["2020 GPT-3 涌现"]
    E --> F["2022.11 ChatGPT 出圈"]
    F --> G["2024-2025 Agent + 推理模型"]
```

**70 年的 AI 史，可以浓缩成一句话**：

> **人类花了 60 年明白"教不会"，花了 5 年学会"让它自己学"，又花了 5 年发现"做大就行"——然后世界就变了。**

理解了这段历史，你就能理解今天 AI 的每一个特点——为什么必须用 GPU、为什么要堆参数、为什么会有幻觉、为什么 OpenAI 一家独大、为什么开源模型现在能反杀。

下面小傅哥和大家一起，正式进入技术拆解。这部分内容来自于各个 LLM 公司所发布的资料，进行的理解、总结，如果有偏差，可以指出。🍻

---

## 二、AI 到底在做什么？（生活直觉版）

### 2.1 它就是在玩文字接龙

你看到的所有 AI——ChatGPT、豆包、文心一言、Claude、Gemini——它们做的事**只有一件**：

> **看一段话，猜下一个字最可能是什么。**

比如你输入"今天天气真不"，它在脑子里算的是：

```mermaid
graph LR
    A["今天天气真不"] --> B{下一个字?}
    B --> C["错 → 70%"]
    B --> D["好 → 20%"]
    B --> E["赖 → 8%"]
    B --> F["想 → 2%"]
```

然后它选概率最高的"错"，把"今天天气真不错"作为新的输入，再猜下一个字……

**一个字一个字接龙，最后接出一整段话。** 就这么简单。

> 💡 **这里有个反直觉的事实**：AI 没有"想好一段话再说出来"的能力。它是**边接边说**的，连它自己都不知道这句话最后会说成什么样。

### 2.2 它怎么学会"哪个字概率高"的？

简单一句话：

> **把整个互联网（书、网页、维基、知乎、新闻、论文……）喂给一个超大的神经网络，让它做亿万次"完形填空"练习。**

```mermaid
graph TB
    A[书籍] --> Z[喂给神经网络]
    B[网页] --> Z
    C[维基百科] --> Z
    D[新闻] --> Z
    E[论文] --> Z
    F[代码] --> Z
    Z --> Y["做完形填空练习 把'今天天气真__'里挖空, 让模型猜'错'"]
    Y --> X[做几万亿次]
    X --> W[模型形成'语感']
```

练了几万亿次之后，它就形成了一种**统计上的语感**——知道在什么上下文下，什么字出现概率最高。

> 这是第一层。听懂了这一层，你已经超过了 80% 的人。下面我们往深里走一层。

---

## 三、那"字"在 AI 眼里长什么样？（技术入门）

### 3.1 Token：AI 眼里的"最小单位"

刚才说"猜下一个字"，其实不太准确。AI 处理的最小单位不是"字"，叫 **Token**（中文有时翻译成"词元"）。

Token 可以是：

- 一个英文单词（如 `cat`）
- 一个英文单词的片段（如 `Learn` + `ing`）
- 一个汉字（如 `人`）
- 一个汉字组合（如 `人工` + `智能`，看 tokenizer 怎么切）

```mermaid
graph LR
    A["原文: Learning AI is fun"] --> B["Tokenizer 切分"]
    B --> C["Learn"]
    B --> D["ing"]
    B --> E[" AI"]
    B --> F[" is"]
    B --> G[" fun"]
```

```mermaid
graph LR
    A["原文: 我爱人工智能"] --> B["Tokenizer 切分"]
    B --> C["我"]
    B --> D["是"]
    B --> E["一个"]
    B --> F["码农"]
```

为什么要这么切？因为这样既能覆盖所有词汇（即使是新词、错别字），又能让模型处理的"词表"控制在几万个的规模，不至于爆炸。

> 💡 **冷知识**：你跟 AI 聊天，按 Token 数收费。中文一个汉字大约 1-2 个 Token，英文一个单词大约 1-1.5 个 Token。所以用中文跟 GPT 聊天比英文贵一点。

### 3.2 Token 怎么变成数字？

计算机只认数字。所以每个 Token 在 AI 眼里其实是一个**编号**：

```mermaid
graph LR
    A["我"] --> A1["#15634"]
    B["是"] --> B1["#27891"]
    C["一"] --> C1["#48127"]
    D["个"] --> D1["#51209"]
    E["码农"] --> E1["#63724"]
```

好——但只有编号还不够。"15634"和"27891"在数学上看就是两个数字，没有任何含义。

我们需要让计算机知道：**"我"和"你"很相似，"狗"和"猫"很相似，"苹果"和"香蕉"很相似**。

这就引出了下一个核心概念——

### 3.3 Embedding：把"意思"变成"坐标"

**Embedding** 是 AI 领域最优雅的发明之一。

它的思路是：**给每个词一个高维空间里的坐标**。坐标相近的词，意思就相近。

为了方便理解，我们把"高维空间"简化成二维：

```mermaid
graph TB
    subgraph 语义空间
        A["猫 (2, 8)"]
        B["狗 (3, 9)"]
        C["老虎 (3, 7)"]
        D["苹果 (8, 2)"]
        E["香蕉 (9, 3)"]
        F["手机 (5, 5)"]
    end
```

在这个空间里：
- 猫、狗、老虎挤在一起（都是动物）
- 苹果、香蕉挤在一起（都是水果）
- 手机离它们都远（电子产品）

**真实的 Embedding 不是 2 维，而是几百到几千维**。维度越多，能表达的语义关系就越细腻。

**Embedding 最神奇的一点：可以做数学运算**

Word2Vec（Google 2013）发现了一个经典现象：

```text
   vec("国王") - vec("男人") + vec("女人") ≈ vec("女王")
   vec("北京") - vec("中国") + vec("法国") ≈ vec("巴黎")
```

**这意味着语义关系被编码成了"方向"**。"性别"是一个方向，"国家-首都"是另一个方向。

```mermaid
graph LR
    A[国王] -.减男人.-> B[?]
    B -.加女人.-> C[女王]
    D[北京] -.减中国.-> E[?]
    E -.加法国.-> F[巴黎]
```

> 💡 **这就是为什么 AI 能"理解"语言**：因为它把所有词变成了坐标，理解就变成了坐标之间的加减乘除——计算机最擅长的事。

到这一层，你已经知道了 AI 处理语言的底层数学了。继续往深走——

---

## 四、手把手教你"算"——Token 和 Embedding 的演进与实战

前面讲了思路，这一节我们**真的动手算**。看完这一节，你能：

- 自己估算一段话有多少 Token
- 自己算两个词之间的"语义距离"
- 知道 Embedding 是怎么"训练"出来的（不是凭空给的坐标）

### A. Token 怎么算？三代演进，由浅入深

#### A.1 第一代：按词切分（Word-level）

最朴素的想法：**遇到空格就切**。

```text
原文：  I love AI
切分：  ["I", "love", "AI"]
Token 数 = 3
```

**问题**：词表会爆炸。英文的"runs / running / ran"会被当成三个完全不同的词；中文更惨——"中国人 / 中国 / 国人"得各占一个位置。最终词表能膨胀到上百万。

#### A.2 第二代：按字符切分（Char-level）

退到极致：**一个字符一个 Token**。

```text
原文：  I love AI
切分：  ["I", " ", "l", "o", "v", "e", " ", "A", "I"]
Token 数 = 9
```

**问题**：词表小了（英文 26 个字母 + 标点就够了），但**序列变得超级长**。一句普通的话拆成几十上百个 Token，模型算起来又慢又笨。

#### A.3 第三代：BPE 子词切分（现代标准）

**BPE（Byte Pair Encoding）**：一种"由数据学出来"的折中方案。

它的思路非常聪明：**让常见的组合保留为一个 Token，少见的拆开**。

举个直观例子，BPE 是这样"训练"出来的：

```text
Step 1: 一开始按字母切
"low low low lowest" → ["l","o","w","l","o","w","l","o","w","l","o","w","e","s","t"]

Step 2: 数哪两个字符相邻出现得最频繁
"l"+"o" 出现了 4 次 → 合并成 "lo"

Step 3: 继续数
"lo"+"w" 出现了 4 次 → 合并成 "low"

Step 4: 继续...
最后形成的词表里就有了 "low" 这个常见单位
而稀有词如 "lowest" 会被切成 "low"+"est"
```

**结果**：常见词整体保留（短而精），罕见词拆成片段（仍能表达）。词表大小被控制在 5 万–10 万之间，覆盖几乎所有可能的输入。

#### A.4 真实 GPT 的切分例子（你可以亲自验证）

下面是一些**真实通过 OpenAI tokenizer 验证过**的 Token 计数（GPT-4 系列使用的 cl100k_base）：

| 原文 | Token 切分（示意） | Token 数 |
|---|---|---|
| `Hello, world!` | `["Hello", ",", " world", "!"]` | 4 |
| `ChatGPT is amazing` | `["Chat", "G", "PT", " is", " amazing"]` | 5 |
| `我爱人工智能` | `["我", "爱", "人工", "智能"]` 或 `["我","爱","人","工","智","能"]` | 4–6 |
| `你好` | `["你","好"]`（每个汉字 1 token，但每个 token 实际占 2-3 字节） | 2 |
| `🚀` | `["🚀"]`（一个 emoji 通常占 2-4 个 byte-level token） | 2–4 |

> 🔧 **想自己验证？** 打开 OpenAI 官方 Tokenizer 页面：[platform.openai.com/tokenizer](https://platform.openai.com/tokenizer)，把任何文本贴进去，它会**实时高亮**告诉你怎么切的、占多少 Token。

#### A.5 一个能用的"心算公式"

工程师常用的近似估算法：

```text
英文：1 token ≈ 0.75 个英文单词 ≈ 4 个英文字符
中文：1 个汉字 ≈ 1.5 ~ 2 个 token
```

**亲自算一下**：

> "今天天气真不错。" — 共 8 个字符（含句号）
> 估算：8 × 1.5 ≈ **12 个 token**（实测 GPT-4：10 个 token，吻合）

> "Hello, my name is GPT-4." — 共 5 个单词 + 标点
> 估算：5 ÷ 0.75 ≈ **7 个 token**（实测：8 个 token，基本吻合）

#### A.6 这能帮你做什么？算钱！

OpenAI GPT-4o 当前价格约（举例）：

```text
输入：$2.50 / 百万 token
输出：$10   / 百万 token
```

**实战**：你写一个客服机器人，每次对话平均：
- 系统 prompt：500 token
- 用户问题：50 token
- AI 回答：300 token

**单次对话成本**：

```text
输入：(500 + 50) tokens × $2.50 / 1,000,000 = $0.001375
输出： 300       tokens × $10   / 1,000,000 = $0.003
合计：≈ $0.0044 / 次对话
```

每天 10000 次对话：**$44/天 ≈ $1320/月**。这就是为什么大型 AI 应用必须精打细算每一个 Token。

---

### B. Embedding 怎么算？从"坐标"到"相似度"

#### B.1 第一代：One-Hot（独热编码）

最早的做法。假设词表有 5 个词：`[猫, 狗, 苹果, 香蕉, 手机]`。

```text
猫    →  [1, 0, 0, 0, 0]
狗    →  [0, 1, 0, 0, 0]
苹果  →  [0, 0, 1, 0, 0]
香蕉  →  [0, 0, 0, 1, 0]
手机  →  [0, 0, 0, 0, 1]
```

**致命问题**：任意两个词的距离都一样（都是 √2），完全没有语义信息。

#### B.2 第二代：共现矩阵（Co-occurrence）

观察："猫"和"狗"经常出现在同一句话里，"猫"和"手机"很少。所以**统计两个词在同一窗口内出现的次数**。

```text
词表：猫 / 狗 / 苹果 / 香蕉 / 手机

共现矩阵（简化）：
        猫  狗  苹果 香蕉 手机
   猫  [ 0,  8,  1,  1,  0 ]
   狗  [ 8,  0,  1,  1,  0 ]
   苹果[ 1,  1,  0,  9,  0 ]
   香蕉[ 1,  1,  9,  0,  0 ]
   手机[ 0,  0,  0,  0,  0 ]
```

**每一行**就是这个词的初代 "Embedding"！你已经能看出来：
- 猫 [0,8,1,1,0] 和 狗 [8,0,1,1,0] 非常像 → 它们语义相近
- 苹果 [1,1,0,9,0] 和 香蕉 [1,1,9,0,0] 非常像 → 它们语义相近

**问题**：维度等于词表大小，太大太稀疏。

#### B.3 第三代：Word2Vec（2013 Google）—— 划时代

把共现矩阵**压缩**到几百维稠密向量。原理简化到极致就是：

> **训练一个小神经网络去做"猜词"游戏：根据中心词猜上下文词。猜对了就调整权重。训练完成后，神经网络中间层的权重，就是每个词的 Embedding。**

```mermaid
graph LR
    A["输入: 猫"] --> B["投影层 查 Embedding 表"]
    B --> C["中间向量 300 维"]
    C --> D[输出层]
    D --> E["预测周围词: '抓','跳','叫'..."]
```

#### B.4 用真实 Embedding 算一次"语义距离"

为了让你看见数字，我们用一个**简化到 4 维**的演示（真实是 300/768/1536 维）：

```text
猫     ≈ [ 0.91,  0.85,  0.10, -0.08]
狗     ≈ [ 0.88,  0.83,  0.12, -0.06]
老虎   ≈ [ 0.82,  0.79,  0.05, -0.10]
苹果   ≈ [ 0.05, -0.12,  0.90,  0.86]
香蕉   ≈ [ 0.08, -0.10,  0.88,  0.91]
手机   ≈ [-0.30, -0.25, -0.40, -0.35]
```

衡量"语义相似度"最常用的是 **余弦相似度（Cosine Similarity）**——也就是衡量两个向量"指向是否接近"。

#### B.5 余弦相似度公式（不要怕，跟着算一遍）

公式：

```text
cosine(A, B) = (A·B) / (|A| × |B|)

其中：
   A·B = a1×b1 + a2×b2 + ... + an×bn   （点积）
  |A|  = √(a1² + a2² + ... + an²)       （向量长度）
```

**手算示例**：算"猫"和"狗"的相似度

```text
A = 猫 = [0.91, 0.85, 0.10, -0.08]
B = 狗 = [0.88, 0.83, 0.12, -0.06]

Step 1: 算点积 A·B
A·B = 0.91×0.88 + 0.85×0.83 + 0.10×0.12 + (-0.08)×(-0.06)
    = 0.8008 + 0.7055 + 0.012 + 0.0048
    = 1.5231

Step 2: 算 A 的长度
|A| = √(0.91² + 0.85² + 0.10² + 0.08²)
    = √(0.8281 + 0.7225 + 0.01 + 0.0064)
    = √1.567
    ≈ 1.2518

Step 3: 算 B 的长度
|B| = √(0.88² + 0.83² + 0.12² + 0.06²)
    = √(0.7744 + 0.6889 + 0.0144 + 0.0036)
    = √1.4813
    ≈ 1.2171

Step 4: 算余弦相似度
cosine(猫, 狗) = 1.5231 / (1.2518 × 1.2171)
              = 1.5231 / 1.5236
              ≈ 0.9997
```

**结论**：猫和狗的相似度 ≈ **0.9997**（满分 1.0），非常相近。

#### B.6 再算"猫"和"手机"对比一下

```text
A = 猫   = [ 0.91,  0.85,  0.10, -0.08]
B = 手机 = [-0.30, -0.25, -0.40, -0.35]

A·B = 0.91×(-0.30) + 0.85×(-0.25) + 0.10×(-0.40) + (-0.08)×(-0.35)
    = -0.273 + (-0.2125) + (-0.04) + 0.028
    = -0.4975

|B| = √(0.09 + 0.0625 + 0.16 + 0.1225) = √0.435 ≈ 0.6595

cosine(猫, 手机) = -0.4975 / (1.2518 × 0.6595)
                = -0.4975 / 0.8255
                ≈ -0.6027
```

**结论**：猫和手机的相似度 ≈ **-0.60**（负数意味着语义相反方向）。

#### B.7 一张表看清楚

| 词对 | 余弦相似度 | 解读 |
|---|---|---|
| 猫 vs 狗 | ≈ 0.9997 | 同类、几乎重合 |
| 猫 vs 老虎 | ≈ 0.997 | 同类、强相关 |
| 苹果 vs 香蕉 | ≈ 0.998 | 同类水果 |
| 猫 vs 苹果 | ≈ 0 | 几乎正交（不相关） |
| 猫 vs 手机 | ≈ -0.60 | 强烈不相关 |

**这就是 RAG（检索增强）的数学基础**：把你的问题变成一个向量，把知识库每段文字变成向量，然后用余弦相似度找最相近的那几段——给 AI 当"参考资料"。

#### B.8 验证经典的"国王 - 男人 + 女人 ≈ 女王"

假设我们有这些向量（演示用，4 维简化）：

```text
国王 = [0.95, 0.20, 0.85, 0.10]
男人 = [0.30, 0.10, 0.80, 0.05]
女人 = [0.30, 0.90, 0.80, 0.05]
女王 = [0.95, 0.95, 0.85, 0.10]
```

**算"国王 - 男人 + 女人"**：

```text
[0.95, 0.20, 0.85, 0.10]
- [0.30, 0.10, 0.80, 0.05]
= [0.65, 0.10, 0.05, 0.05]

[0.65, 0.10, 0.05, 0.05]
+ [0.30, 0.90, 0.80, 0.05]
= [0.95, 1.00, 0.85, 0.10]
```

把结果 `[0.95, 1.00, 0.85, 0.10]` 跟"女王" `[0.95, 0.95, 0.85, 0.10]` 比一比——几乎完全一致！

> 💡 **这就是 Word2Vec 当年震惊学术界的原因**：语义居然真的能像三维空间里的几何向量一样进行加减运算。

#### B.9 真实场景中 Embedding 怎么用？

你完全可以自己上手：

```text
1. OpenAI 提供 text-embedding-3-small 模型
   输入文本 → 输出 1536 维向量

2. 调用一次大约 1024 token 的成本：≈ $0.00002

3. 把你的所有文档都跑一遍 → 存进向量数据库（Pinecone/Milvus/Chroma）

4. 用户提问时:
   - 把问题转成 1536 维向量
   - 在数据库里找余弦相似度最高的 Top-5 段落
   - 把这 5 段 + 用户问题打包发给 GPT-4
   - GPT-4 基于这些"开卷资料"回答
```

**这就是企业 AI 助手的标准做法**。看完这一节，你已经知道它的底层在算什么了。

---

### C. 一句话总结这一层

> Token 是 AI 的"字"，Embedding 是 AI 的"语义坐标"。
>
> **算 Token = 算钱**；**算 Embedding 距离 = 算意思**。
>
> 这两件事是当代 AI 工程最基础、最值钱的两个计算。

---

## 五：AI 怎么"看懂"一整句话？（注意力机制）

### 5.1 一个问题：词序很重要

"小狗咬小孩"和"小孩咬小狗"用了一模一样的词，但意思完全相反。

光有 Embedding 不够，模型必须知道**词和词之间的关系**。

### 5.2 注意力机制：让每个词"环顾四周"

2017 年 Google 提出了 **Transformer 架构**，里面最核心的发明叫 **Self-Attention（自注意力）**。

它的思路用大白话说就是：

> **每个词在被理解的时候，都要回头看一下句子里的其他词，给每个词分配一个"关注度"。**

比如这句话："**那只猫**因为太累了，所以它睡着了。"

模型在处理"它"这个词时，会做什么？

```mermaid
graph TB
    A["它"] -->|关注度 0.85| B["那只猫"]
    A -->|关注度 0.05| C["因为"]
    A -->|关注度 0.03| D["太累了"]
    A -->|关注度 0.02| E["所以"]
    A -->|关注度 0.05| F["睡着了"]
```

"它"这个词，把 85% 的注意力都放到了"那只猫"上——所以模型知道："它"指的是"那只猫"。

**这就是 AI 能"看懂"语言指代、上下文、长距离关系的原因。**

> 📖 **幕后故事：注意力机制是怎么"反客为主"的**
>
> 注意力机制最早不是为了取代 RNN 而生的，它本来只是 RNN 的一个**辅助插件**——2014 年 Bengio 团队为了让翻译模型记住更长的句子而发明。
>
> 当时大家把它当成"调味料"：往 RNN 里加一勺，效果更好。
>
> 直到 2017 年那 8 个 Google 研究员做了一件事——他们想："**既然注意力这么好用，那干脆把 RNN 全删了，只留注意力呢？**"
>
> 当时连他们自己都没把握。结果一上线，**所有人都傻眼了**：不仅效果好，速度还快了几十倍。
>
> 这就是 AI 史上著名的"调味料反客为主"事件。**很多颠覆性的创新，都不是设计出来的，是"试出来的"**。

### 5.3 整张图：一段话进入模型后发生了什么

把前面学的串起来，看一段文本是怎么流过 AI 大脑的：

```mermaid
graph TB
    A["输入文本: '我是一个码农'"] --> B["Tokenizer 切分"]
    B --> C["Token: 我 / 是 / 一 / 个 / 码农"]
    C --> D["查表:Token → 编号"]
    D --> E["编号: 15634 / 27891 / 48127 / 51209 / 63724"]
    E --> F["查 Embedding 表"]
    F --> G["每个 Token 变成 一个高维向量"]
    G --> H["进入 Transformer"]
    H --> I["Self-Attention 每个词环顾四周"]
    I --> J[经过几十层处理]
    J --> K["输出: 下一个 Token 的概率分布"]
    K --> L["采样选一个 Token"]
    L --> M["把新 Token 拼回去, 重复整个过程"]
```

> 💡 这就是 GPT 系列、Claude、Gemini、文心、通义、DeepSeek……**所有现代大模型的统一架构**。

---

## 六、模型是怎么"学会"这一切的？（训练）

到现在为止，我们讲的都是**模型已经训练好之后**怎么用。那它最开始是怎么学会的？

现代大模型的训练分**三步**，缺一不可。

### 6.1 第一步：预训练（Pre-training）—— 让 AI "读完整个互联网"

```mermaid
graph LR
    A[海量文本] --> B[做完形填空]
    B --> C[模型猜错了]
    C --> D[调整模型参数]
    D --> B
    B --> E[模型猜对了]
    E --> F[巩固参数]
    F --> B
```

- **目标**：学会语言规律和世界知识
- **数据**：几十 TB 的网页、书籍、代码
- **方法**：不停做完形填空
- **代价**：需要几千张顶级 GPU、训练几个月、烧掉几千万到几亿美元

这一步完成后，模型已经知识渊博，但**不太会聊天**——你问一句它可能给你接龙一段维基百科。

### 6.2 第二步：监督微调（SFT）—— 教 AI "怎么好好说话"

```mermaid
graph LR
    A[人工写的高质量对话] --> B[喂给模型]
    B --> C["模型学会: 遇到问题该这样回答"]
```

- **目标**：让模型学会"对话格式"和"指令遵循"
- **数据**：几万到几十万条人工精心编写的"问-答"对
- **方法**：让模型模仿优秀回答

这一步之后，模型会聊天了，但还会出现各种**不太合适**的回答——比如说脏话、给危险建议、答非所问。

### 6.3 第三步：RLHF —— 让 AI "懂人话、合人意"

RLHF = **基于人类反馈的强化学习**。这是 ChatGPT 真正惊艳世人的秘密武器。

```mermaid
graph TB
    A["同一个问题 让模型生成多个回答"] --> B["人类标注员排序 这个比那个好"]
    B --> C["训练一个'评分模型' 学会模仿人类喜好"]
    C --> D["让主模型生成回答 评分模型打分"]
    D --> E["根据分数 用强化学习调整主模型"]
    E --> D
```

- **目标**：让模型回答**符合人类偏好**——有用、诚实、无害
- **数据**：人类对模型回答的偏好排序
- **方法**：强化学习

> 💡 **这里有个有趣的副作用**：RLHF 后的模型，会变得"过度自信"和"过度礼貌"。因为人类标注员喜欢自信、礼貌的回答。所以现代 AI 模型反而更容易**装作自己什么都知道**——这就是幻觉的一个根源。

> 📖 **幕后故事：ChatGPT 那 5 万小时的"血汗"**
>
> RLHF 听起来很高大上，但它其实极其依赖**人**。
>
> 训练 ChatGPT 时，OpenAI 雇了大量的标注员（很多是肯尼亚的外包公司），给模型生成的成千上万条回答**做排序**："这条比那条好"、"这条有害"、"这条更礼貌"……
>
> 据 *Time* 杂志报道，肯尼亚的标注员时薪不到 2 美元，每天要看大量包含暴力、色情、仇恨内容的文本，**心理负担巨大**。这是 ChatGPT 光鲜表面下不为人知的一面。
>
> 这件事也说明了一个事实：**AI 不是凭空"学聪明"的，它的每一点"懂事"，背后都是大量人类的劳动**。下次你跟 ChatGPT 聊天觉得它特别贴心时，可以记住——那贴心是几千个人手把手"调教"出来的。

### 6.4 训练全景图

```mermaid
graph LR
    A[互联网海量文本] --> B["Step 1: 预训练"]
    B --> C["基础模型 知识渊博但不会聊天"]
    C --> D["Step 2: SFT 微调"]
    D --> E["对话模型 会聊天但偶尔失控"]
    E --> F["Step 3: RLHF"]
    F --> G["最终模型 有用 / 诚实 / 无害"]
    G --> H[发布给用户]
```

---

## 七、为什么"大"模型才有用？（涌现）

### 7.1 一个奇怪的现象

研究人员发现一个反直觉的现象：

- 模型小的时候，做某项任务的能力 = 0
- 模型变大一点，能力还是 = 0
- 模型再变大，能力依然 = 0
- ……
- 模型大到某个临界点，**能力突然跳到 80%！**

这个现象叫 **涌现（Emergence）**。

```mermaid
graph LR
    A["1亿参数 不会做数学"] --> B["10亿参数 还是不会"]
    B --> C["100亿参数 仍然不会"]
    C --> D["1000亿参数 突然会了!"]
```

### 7.2 一个生活化的类比

想象小孩学语言：

- 6 个月：什么都不会说
- 12 个月：会说"妈妈、爸爸"
- 18 个月：还是只会单词
- **2 岁：突然开始说完整句子**

不是大脑容量缓慢提升，是**积累到了某个量级，质变才发生**。

大模型也是这个道理。

### 7.3 哪些能力是"涌现"出来的？

- **逻辑推理**：能做多步数学题
- **代码能力**：能写出能跑的程序
- **跨语言翻译**：没专门训练过中翻法，也能做
- **角色扮演**：能稳定扮演一个角色
- **指令遵循**：能按你说的格式输出

> 💡 这就是为什么"小模型"和"大模型"不仅仅是程度差异，而是**能力级别的差异**。这也是为什么各家公司在拼命堆参数。

> 📖 **现实拷问：为什么 Qwen 0.6B 比 Qwen 9B 差那么多？**
>
> 你下载过 Ollama 或者 LM Studio 的话，会看到同一个家族（比如 Qwen、Llama、DeepSeek）有一堆不同尺寸：0.5B / 1.5B / 3B / 7B / 9B / 14B / 32B / 72B……
>
> 一个特别常见的疑问是：
>
> > **"模型名字都一样、训练数据也都一样，凭什么 9B 就能聊天写代码，0.6B 连话都说不利索？参数量才差 10 几倍而已啊？"**
>
> 这正是"涌现"在你电脑上的真实写照。我们一层层拆开看。
>
> ---
>
> **① 参数差 10 倍，"知识容量"差的可不止 10 倍**
>
> 大模型本质是把世界知识"压缩"进参数里（前面讲过的有损压缩）。
>
> - 0.6B 模型 = 约 0.6 GB（FP16）= 一本小百科全书的容量
> - 9B 模型 = 约 18 GB = 大约一座小型图书馆
>
> 但**知识不是线性增长的**。0.6B 必须做艰难的取舍——哪些常识保留？哪些专业领域舍弃？最后保留下来的只是"语言的形状"和最高频的事实。问它"乔布斯哪年去世"它可能瞎编；问它"红楼梦谁写的"它也未必能稳。
>
> 9B 大到能同时塞下：通用常识 + 多种语言 + 数学公式 + 编程语法 + 文学风格……一个网络里塞十几个"子专家"，而 0.6B 只能塞一个糊涂的"通才"。
>
> ---
>
> **② 涌现能力的"门槛"，0.6B 根本没跨过去**
>
> 大模型有些能力是"全有或全无"的，存在一个最低参数门槛：
>
> | 能力 | 大约门槛 | 0.6B 表现 | 9B 表现 |
> |---|---|---|---|
> | 流畅说人话 | ~0.3B | 勉强能 | 很自然 |
> | 跟从复杂指令 | ~1B | 经常跑偏 | 大体能跟 |
> | 简单数学（两位数运算） | ~3B | 几乎不行 | 能做对一部分 |
> | 多步推理 / Chain-of-Thought | ~7B | 完全做不到 | 开始有 |
> | 写能跑的代码 | ~7B | 极不稳定 | 简单题能写 |
> | 角色扮演 / 长对话保持人设 | ~7B | 几轮就乱 | 稳定 |
>
> 这就像盖楼——**没盖到 5 层之前，你装电梯没意义**。0.6B 的容量根本"撑不起"推理这种复杂能力。
>
> ---
>
> **③ 一个更深的原因：模型不仅在记知识，还在记"思考的回路"**
>
> 大模型内部有研究者发现了所谓的"电路（circuit）"——多个神经元协同实现某种功能，比如：
>
> - **指代消解电路**：理解"它"指代前面哪个名词
> - **算术电路**：执行多步加减
> - **括号匹配电路**：写代码时配对 `{` `}` `(` `)`
>
> 这些电路通常需要**几亿到几十亿参数**才能稳定形成。0.6B 模型连这些"思考的回路"都没长出来，所以它的失败不是"知识不够"，而是**根本没装上这些功能模块**。
>
> ---
>
> **④ 实战对比：一个真实的题目，三个尺寸的回答**
>
> 题目：**"小明有 12 个苹果，分给 3 个朋友，每人一样多。如果再给每个朋友 2 个，每人现在有多少？"**
>
> - **Qwen 0.6B 回答（典型）**："小明给每个朋友 4 个苹果。" ❌（没算第二步）
> - **Qwen 3B 回答（典型）**："每人分到 4 个，再加 2 个，所以是 6 个。" ✅（步骤简单，但能对）
> - **Qwen 9B 回答（典型）**："第一步：12÷3 = 4。每人 4 个。第二步：再加 2 个，每人 4+2 = 6 个。最终答案：每人 6 个苹果。" ✅✅（步骤清晰、过程可验证）
> - **Qwen 32B 回答**：可能还会主动给一个表格、举一反三、提示你"如果数字变成 15 怎么算"。
>
> 注意——**不只是"对/错"的差别，是"会不会思考"的差别**。
>
> ---
>
> **⑤ 那 0.6B 还有用吗？有！但要用对地方**
>
> 别看 0.6B"傻"，它有**致命的优势**：
>
> - **快**：在普通手机/树莓派上都能跑，延迟几十毫秒
> - **小**：500MB 以下，能塞进任何设备
> - **便宜**：API 价格可以低到 9B 的 1/20
>
> 所以它的舞台是：**简单分类、智能路由、标题生成、关键词抽取、敏感词过滤**——这些任务你用 9B 是浪费，用 0.6B 又快又便宜。
>
> 业界一个很火的设计模式叫 **"模型路由器"**：
>
> ```text
> 用户问题 → 0.6B 模型先判断"这是个简单问题还是复杂问题？"
>           ↓
>      简单 → 给 3B 模型回答（便宜）
>      复杂 → 给 70B 模型回答（贵但准）
> ```
>
> 这样既能保证质量，又能把成本压低 80%。
>
> ---
>
> **⑥ 一句话总结**
>
> > **小模型不是"差版本"，是"完全不同的物种"。**
> > **0.6B 是麻雀**（敏捷、便宜、做小事），**9B 是中型鸟**（能飞远），**70B 是猛禽**（能抓大猎物）。
> > 不存在"以小搏大"，只存在"用对地方"。
>
> 选模型的核心心法：**先问任务复杂度，再选参数尺寸**。不要一上来就用最大的，也别奢望小模型干大事。

> 📖 **幕后故事：GPT-3 是怎么让全世界改变看法的**
>
> 2020 年 5 月，OpenAI 发布 GPT-3。当时业内的反应是分裂的：
>
> - **学术界**：嗤之以鼻。"不就是个更大的 GPT-2 吗？没有任何架构创新，靠堆参数算什么科研？"
> - **工程师圈**：开始疯传一些 demo。
>
> 然后真正改变历史的事件发生了——**一位推特用户 Sharif Shameem 用 GPT-3 做了个 demo**：他对着 GPT-3 用自然语言描述："我要一个有红色按钮的页面，按钮下面有一段欢迎文字。" GPT-3 直接生成了能跑的 HTML 代码。
>
> 这条推特一夜爆红。所有人才意识到：**这玩意儿不是"更好的语言模型"，它是个"通用任务求解器"**。
>
> 没人教过 GPT-3 怎么写 HTML，没人专门训练过它"理解 UI 描述"。它就是在预训练里**自己学会了**。
>
> 这就是涌现最让人震撼的地方——**模型在某个尺寸之后，开始"举一反三"**。这种能力不是任何研究员设计出来的，**它是"长出来"的**。这件事也彻底改变了整个 AI 行业的研究方向：从"我设计什么算法"变成了"我怎么把模型做得更大"。

---

## 八、为什么 AI 会"胡说八道"？（幻觉的本质）

终于到了大家最关心的问题。

### 8.1 幻觉不是 Bug，是机制决定的

回到我们最开始的核心比喻：**AI 是文字接龙选手**。

它的工作原理是"必须接出下一个字"。它**没有**：

- ❌ "我不知道"的开关
- ❌ 一个事实数据库可以查
- ❌ 区分"真"和"假"的能力

它只有一个**概率分布**。

```mermaid
graph TB
    A["你问:'某某公司在上海的地址?'"] --> B{模型怎么想}
    B --> C["训练数据里这类问题 通常会跟一个具体地址"]
    C --> D[那我也接一个像样的地址]
    D --> E["输出: 上海市浦东新区... 编出一个完全不存在的地址"]
```

它不是"故意撒谎"——**它根本不知道什么叫"撒谎"**。

它只是在做它最擅长的事：**让接出来的话看起来通顺、合理、像那么回事**。

### 8.2 幻觉的数学必然性

2024 年 OpenAI 自己发了一篇论文 *Why Language Models Hallucinate*，证明了一件事：

> **在标准的训练和评测体系下，"猜一个"比"承认不知道"得分更高。所以模型会被训练成"宁可瞎编也不空着"。**

这意味着幻觉**不能靠堆参数消除**，必须靠**外部系统**解决。

### 8.3 工程上怎么对付幻觉？

业界的标准做法叫 **RAG（检索增强生成）**：

```mermaid
graph LR
    A[用户提问] --> B["先去你的知识库 检索相关资料"]
    B --> C["把资料塞给 AI 说: 基于这些资料回答"]
    C --> D["AI 不再凭空编造 而是基于资料组织答案"]
```

打个比方：

- **没 RAG** = 让学生闭卷考试 → 容易瞎编
- **用 RAG** = 让学生开卷考试 → 答案有根有据

```mermaid
graph TB
    A["公司内部文档 产品手册 知识库"] --> B[切成小块]
    B --> C["计算每块的 Embedding 存进向量数据库"]
    D[用户提问] --> E["计算问题的 Embedding"]
    E --> F["从向量数据库 找最相似的几块"]
    C --> F
    F --> G["把这几块 + 用户问题 一起发给大模型"]
    G --> H[模型基于资料生成答案]
```

> 💡 **这就是为什么"企业内部 AI 助手"基本都是 RAG 架构**：你不能让通用 AI 知道你公司内部的事，但你可以"开卷"让它现场查。

---

## 九、AI 不只是聊天——Agent 时代来了

### 9.1 从"会说"到"会做"

到目前为止，我们讲的 AI 都只能"输出文字"。但 2024 年开始，业界进入了 **Agent（智能体）** 时代。

什么是 Agent？一句话：

> **会用工具、能完成任务的 AI。**

```mermaid
graph TB
    A["传统 AI: 只会输出文字"]
    B["Agent: 会用工具、能采取行动"]

    A --> A1[你问天气]
    A1 --> A2[它瞎编一个天气]

    B --> B1[你问天气]
    B1 --> B2["它调用天气 API"]
    B2 --> B3[拿到真实数据]
    B3 --> B4[告诉你准确天气]
```

### 9.2 Agent 的核心组件

```mermaid
graph TB
    A[用户任务] --> B["Agent 大脑 大模型"]
    B --> C{需要做什么?}
    C --> D[调用搜索引擎]
    C --> E[执行代码]
    C --> F[读取数据库]
    C --> G[发送邮件]
    C --> H[操作浏览器]
    D --> I[拿到结果]
    E --> I
    F --> I
    G --> I
    H --> I
    I --> J{任务完成?}
    J -->|没有| C
    J -->|完成| K[输出最终结果]
```

简单说，Agent = **大模型 + 工具集 + 一个循环**：

1. 看任务
2. 想想要不要用工具，用哪个
3. 用工具，拿到结果
4. 想想下一步
5. 循环，直到任务完成

### 9.3 真实世界的 Agent 例子

- **Cursor / Claude Code / WaLiCode**：你说"帮我把这个功能改成异步的"，它自己读代码、改代码、跑测试。
- **Devin**：号称"AI 软件工程师"，能从一个 GitHub Issue 开始，自己分析、修代码、提 PR。
- **企业客服 Agent**：用户问问题，它查订单、查物流、查退款政策、给出处理方案。

### 9.4 Agent 的现状：很美好，但很难

实话说，Agent 目前还远没到"完全替代人"的地步。原因：

```mermaid
graph LR
    A["第1步: 90% 正确"] --> B["第2步: 90% 正确"]
    B --> C["第3步: 90% 正确"]
    C --> D["..."]
    D --> E["第10步: 整体正确率 = 0.9 的 10 次方 ≈ 35%"]
```

**每一步都可能出错，错误会累积**。所以现在所有靠谱的 Agent 都不是"完全自主"，而是：

> **把工作流程画成一张图，AI 在图上"沿着轨道走"，关键节点由 AI 决策，但整体框架由人定。**

这叫 **Workflow + LLM**，是目前最务实的工业级 Agent 模式。

> 📖 **幕后故事：Devin 的"过山车"与 DeepSeek-R1 的"低成本奇迹"**
>
> **Devin 的故事**：2024 年 3 月，Cognition Labs 发布了 Devin，宣称是"世界上第一个 AI 软件工程师"。演示视频里它从看 Issue、读代码、写代码、跑测试、提 PR 一气呵成，**整个硅谷都疯了**。公司估值一夜从 0 飙到 20 亿美元。
>
> 但几个月后，AI 评测博主 *Internet of Bugs* 发了一条扒皮视频，逐帧分析 Devin 的演示——**发现里面有大量精心剪辑、跳过失败、反复重试**。真实使用率远低于演示。
>
> 这给整个行业泼了一盆冷水，让大家清醒过来：**Agent 离"完全自主"还很远，目前最务实的方向是"AI 加速人，而不是替代人"**。Cursor、Claude Code 这种"AI 提议、人确认"的模式，反而活得最滋润。
>
> **DeepSeek-R1 的故事**：2025 年 1 月 20 日，杭州一家叫 DeepSeek 的小公司发布了 R1 模型——**推理能力对标 OpenAI 当时最贵的 o1，而背后的基础模型 V3 训练成本约 557 万美元**（OpenAI 同级模型据估算花了上亿美元）。更狠的是：**完全开源、技术报告全公开**。
>
> 这一事件直接引发了**全球资本市场地震**：2025 年 1 月 27 日，NVIDIA 股价单日暴跌约 17%、市值蒸发近 5890 亿美元，刷新美股单日单股市值蒸发纪录。原因很简单——如果顶级 AI 能用 1/20 的成本做出来，那"无脑买卡"的逻辑就动摇了。
>
> R1 还有一个更重要的技术贡献：它证明了**仅靠强化学习（R1-Zero 阶段），不经过 SFT，模型就能自发学会推理、反思、自我纠错**。这是大模型领域近三年最重要的发现之一。
>
> 这两个故事合在一起说明一件事——**AI 行业现在的速度，是按"周"在变化的**。今天的明星，下个月可能就被反超；今天看似遥不可及的能力，明年可能开源到你能在自己电脑上跑。**保持学习、不要押宝任何单一技术**，是这个时代的生存之道。

---

## 十、未来三年，AI 会变成什么样？

最后给你看一张全局图，整个 AI 工业栈大概长这样：

```mermaid
graph TB
    A["基础大模型层 GPT-4 / Claude / Gemini / DeepSeek / Qwen"]
    A --> B["能力增强层 RAG / Function Calling / 长上下文"]
    B --> C["Agent 编排层 LangChain / LangGraph / AutoGen"]
    C --> D["应用层 Cursor / Devin / 各种 AI 助手"]
    D --> E[用户]
```

未来三年值得关注的几条线：

1. **推理时计算（Test-Time Compute）**：让模型"想得更久 = 答得更准"。OpenAI o1/o3、DeepSeek-R1 已经验证了这条路。
2. **多模态**：从只懂文字，到能看图、听音、操作屏幕、控制机器人。
3. **长期记忆**：让 AI 记住你是谁、跟你聊过什么，跨会话保留。
4. **AI 原生应用**：不是给老软件加 AI，而是从头设计的 AI-first 产品。（可能的最终形态）

---

## 十一、用今天学的理论，看懂你昨天遇到的 AI

讲了这么多概念，你可能想问：**这些理论跟我每天用 AI 的体验有啥关系？**

关系大了。我们挑 6 个**几乎人人都遇到过**的真实场景，用前面学的理论给你"翻译"一下——你会发现，**所有看起来奇怪的 AI 行为，背后都有原因**。

### 场景 1：每次问同一个问题，AI 给的答案都不一样

> "我昨天问它写朋友圈，今天再问，文案完全不一样了。它不记得我吗？"

**用理论解释**：

- 它**真的不记得**——除非你在同一个对话窗口。每次新对话，AI 是"白纸一张"。
- 即使同一对话，它的输出也带**采样随机性**（Temperature 参数）。同样的"下一个 token 概率分布"，每次采样都可能采到不同的词。
- 这是 **第一层「文字接龙」+ Temperature 机制** 在起作用。

**怎么用**：
- 想要稳定结果（写代码、抽取数据）→ 让对方降低 temperature 或明确说"请给确定的答案"
- 想要创意发散（起名、文案）→ 让它多生成几个版本

---

### 场景 2：让它写一篇 5000 字的长文，越往后越"水"、越跑题

> "前 1000 字写得挺好，后面就开始重复、说废话、甚至偏离主题。"

**用理论解释**：

- 这就是 **第三层提到的注意力机制**和 **第六层提到的"Lost in the Middle"** 的工程后果。
- AI 写到后面时，前面已经写过的内容塞在它的"上下文"里。**上下文越长，每个 token 分到的"注意力预算"就越少**——它就开始"看不清"自己之前写了什么。
- 加上"接龙"特性，前面如果出现一个偏题的句子，后面会沿着这条偏题路径越走越远。

**怎么用**：
- 别让它一次写 5000 字。**拆成"先写大纲 → 逐节展开"**。
- 长文写完后让它**重新校对一遍主题一致性**。

---

### 场景 3：明明很简单的算术题，AI 都能算错

> "我让它算 23 × 47，它给了我一个看起来很对但实际错了的数。"

**用理论解释**：

- 回到 **第一层**：AI 是**接龙**，不是计算器。它生成 23×47 的结果时，是在"猜下一个数字最可能是什么"，**不是真的在做乘法**。
- **第六层「幻觉」** 也在这里发挥：它不会承认"我算不来"，会硬着头皮编一个看起来合理的数字。

**怎么用**：
- 让它**列出计算步骤**（"先算个位、再算十位"），借助"Chain-of-Thought"机制，准确率会显著提升。
- 涉及钱、统计、严肃数据 → **永远用计算器/代码再核对一遍**。
- 高级用法：让它"用 Python 算"，让 AI 调用工具（**第七层 Function Calling**）。

---

### 场景 4：问"现在比特币多少钱"，它说一个 2 年前的数字

> "我问它今天的天气、最新新闻、股价，它给的全是过时的。"

**用理论解释**：

- **第四层「训练」** 告诉我们：模型的知识来自**训练数据**，训练数据有**截止日期**。
- 一旦训练完成，模型就"冻结"了——它不会自己上网。
- 它给的"实时"数字，本质上是**幻觉**——基于过去数据猜了一个"合理的样子"。

**怎么用**：
- 实时信息 → **用带"联网搜索"功能的模式**（ChatGPT 的搜索按钮、Perplexity、豆包联网模式）。
- 这背后就是 **第七层 Agent 的工具调用** —— AI 自己去搜索引擎查，再回答你。

---

### 场景 5：上传一份 100 页 PDF，问里面的细节它答错

> "我把公司年报扔给它，问'第三季度净利润',它给的数字跟原文对不上。"

**用理论解释**：

- 这是经典的 **"长上下文塌陷"**（前面提过）。100 页 PDF 大约 5-10 万 token，**中段信息最容易被忽略**。
- AI 在长文档里"指认"具体数字时，注意力可能根本没真正聚焦到原文那一行。

**怎么用**：
- **不要扔整本**。先让它生成目录或摘要 → 再针对你关心的章节单独提问。
- 或者用支持 **RAG（第六层「开卷考试」）** 的工具：把 PDF 切片入库，提问时只检索相关片段给 AI。
- 关键数字 → **永远要求它"原文引用"**——它就不容易瞎编。

---

### 场景 6：同一个 Qwen 模型，0.6B 答非所问，9B 又快又准

> "都叫 Qwen，参数差 10 几倍，结果天差地别。"

**用理论解释**：

- 这就是 **第五层「涌现」** 的现实写照。
- 推理、跟从复杂指令、写代码——这些是**有门槛的能力**，0.6B 根本没跨过去。
- 不是"差一点"，是**"完全没装上这个功能模块"**。

**怎么用**：
- 简单任务（分类、关键词、标题）→ 用 0.6B / 1.5B，便宜又快。
- 严肃任务（写代码、写报告）→ 至少 7B 起步。
- 高级用法：用**模型路由器**（小模型先判断、再决定派给谁），成本可降 80%。

---

### 一张总结表：一眼看懂"理论 → 现象 → 对策"

| 你遇到的现象 | 背后理论 | 对策 |
|---|---|---|
| 答案每次都不一样 | 文字接龙 + Temperature | 降温 / 明确要求 |
| 长文越写越水 | 注意力被稀释 / Lost in the Middle | 分段写、写完再校 |
| 算术错得离谱 | 接龙 ≠ 计算 + 幻觉 | 列步骤 / 用工具 |
| 实时信息过时 | 训练数据有截止日期 | 开联网模式 |
| 长 PDF 答错细节 | 长上下文塌陷 | 切片提问 / 要求原文引用 |
| 小模型答非所问 | 涌现门槛 / 容量不够 | 选对参数尺寸 |

> 💡 **学习 AI 最好的方式，不是背概念，是在你下次踩坑时——能立刻说出"这是哪个机制在作怪"**。
>
> 当你能用"上下文塌陷"解释一次长文档失误，用"涌现"解释一次模型升级带来的飞跃——你就真正"懂 AI 了"。

---

## 终章：把整个故事串起来

最后用一张图，把这篇文章讲的所有概念串成一个完整的故事：

```mermaid
graph TB
    subgraph 1.数据准备
        A1[整个互联网文本]
    end

    subgraph 2.基础表示
        B1["Tokenizer 切分"]
        B2["Embedding 把词变坐标"]
    end

    subgraph 3.架构核心
        C1["Self-Attention 每个词看其他词"]
        C2["Transformer 几十层堆叠"]
    end

    subgraph 4.训练
        D1["预训练: 完形填空"]
        D2["SFT: 学会聊天"]
        D3["RLHF: 符合人类偏好"]
    end

    subgraph 5.涌现的能力
        E1[语言]
        E2[推理]
        E3[代码]
        E4[翻译]
    end

    subgraph 6.局限
        F1[幻觉]
        F2[知识过时]
        F3[数学差]
    end

    subgraph 7.工程对策
        G1["RAG 开卷考试"]
        G2["Function Calling 用工具"]
        G3["Agent 自主完成任务"]
    end

    A1 --> B1 --> B2 --> C1 --> C2 --> D1 --> D2 --> D3 --> E1
    D3 --> E2
    D3 --> E3
    D3 --> E4
    E1 --> F1
    E1 --> F2
    E1 --> F3
    F1 --> G1
    F2 --> G1
    F3 --> G2
    G1 --> G3
    G2 --> G3
```

读完这篇文章，根据你的理解程度，可以分成三档：

| 档位 | 你应该能说出 |
|---|---|
| **入门** | AI 是文字接龙，会胡说，得自己核对 |
| **进阶** | AI 把词变成坐标，靠注意力理解上下文，靠预训练+SFT+RLHF 三步学习 |
| **熟手** | 我知道大模型 + RAG + Agent + MCP（后续分享） + Skills（后续分享） 怎么组合，能跟工程师讨论方案 |

如果你看完只到了"入门"档，也没关系——把这篇文章收藏，过一周再读一遍，你会发现很多之前没注意的细节变清晰了。

**理解 AI 是这个时代的复利能力。早一点搞明白，未来几年的红利就早一点吃到。**

---

## 附：本文涉及的核心概念速查表

| 概念 | 一句话解释 |
|---|---|
| **Token** | AI 眼里的最小单位，像字也像词 |
| **Embedding** | 把词变成多维空间里的坐标，坐标近 = 意思近 |
| **Self-Attention** | 每个词去"环顾"句子里的其他词，理解关系 |
| **Transformer** | 把 Attention 堆叠几十层形成的大脑结构 |
| **预训练** | 喂海量文本做完形填空，让模型学到语言和知识 |
| **SFT** | 用高质量对话样本，教模型怎么聊天 |
| **RLHF** | 用人类偏好反馈，让模型变得更"懂人" |
| **涌现** | 模型大到某个临界点，新能力突然出现 |
| **幻觉** | AI 编造看似合理但实际错误的内容 |
| **RAG** | 检索增强生成 = 让 AI 开卷考试 |
| **Function Calling** | 让 AI 会调用外部工具 |
| **Agent** | 会用工具、能完成任务的 AI |

把这张表存下来，下次看到这些词，你就不会再发怵了。**愿你不仅会用 AI，也理解 AI；不仅不被它取代，还能驾驭它。** 🚀

---

### Md Ai Ai Ssh Opencode (`docs/md/ai/ai-ssh-opencode.md`)

---
title: ai ssh opencode
lock: need
---

# ai ssh opencode 命令行工具

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115811243001489&bvid=BV1hciNB9EsE&cid=35087846352&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

天才般的发明，**ai ssh 命令行工具**，让 ai 的使用不只局限在 `ai 对话提问`、`ai idea 辅助编码`，也可以直接让操作系统具备 ai 能力。其实这才是我一直想要的东西！😄

<div align="center">
	<img src="https://bugstack.cn/images/article/project/chatgpt/openai-01.jpg" width="150px"/>
</div>

**ai 正在改变产品设计！**

2025年，是 ai agent 智能体爆发的一年，它所提效的接入方式可以分三层来看；

先是中间这一层，是 ai agent 接入服务和软件，像是大家使用的 trae.ai 或者小傅哥分享过的 [draw.io + ai](https://bugstack.cn/md/road-map/draw.io.html)，以及各个互联网公司用 ai 提效做的一些场景客服，系统巡检，日志分析等。

之后上面这一层，是从用户视角，模拟用户行为使用软件，而不是直接接入到软件api上。它使用的方式是 AutoGLM-Phone-9B 手机模型，以 ADB 或者无障碍模式，让手机可以接收用户指令，完成操作。如；`打开京东，搜索东北老式麻辣烫，加入购物车，以默认地址，进行支付购买。下单支付完成后，微信发给xxx告诉，她预计送达时间。` 如果感兴趣，可以基于这篇文章进行实践。[《手机 + agent，这是要掀桌子！》](https://bugstack.cn/md/algorithm/model/autoglm-phone-agent.html)

然后底下这一层，是从系统层面，不再依赖于直接对接某个软件，某个api，而是以系统层面直接操作软件，或者完成整个行为动作。如，在云服务器/本地，配置好 jdk、maven、docker 环境，之后帮我拉取 git clone xxx 仓库代码，本地完成 maven 构建和启动。以及在遇到问题时候，让 ai 直接检索并处理都是非常可以的。

好，那接下来，小傅哥给大家分享下，如何安装一个 ai ssh 工具（没有这个教程，很多人是安装不上的！）。

>🧧 文末提供了小傅哥所有编程实战项目获取方式，一次加入即可获得19个已完结的实战项目，也有非常多的 AI 类项目，一定要补充学习！

## 一、工具介绍

ai ssh 是命令行工具，可以安装到 Mac、Windows、Linux 上，以通过 terminal（终端）直接操作系统进行使用。它的场景也包括你打开的 IntelliJ IDEA 下面的 terminal 终端中使用，这样就天然的嵌入到了 IntelliJ IDEA 中了，非常方便。

目前这类的 ai ssh 命令行工具软件也非常多，包括；[opencode.ai](https://opencode.ai/)、[claude](https://claude.com/product/claude-code)、[openai codex](https://github.com/openai/codex)、[阿里千问 - qianwen code](https://github.com/QwenLM/qwen-code)，都出了对应的软件。

在整体体验后，效果还是都不错的，这里是 opencode 的终端使用截图；

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-01.png" width="650px"/>
</div>

- opencode 默认提供了一些免费模型，可以输入 `/models` 进行选择。
- 另外还可以通过配置文件，添加其他模型，如 claude 模型、openai 模型、小米模型等。

## 二、软件安装

以下软件安装，会需要用到 gcc、nodejs 20+ 版本，建议安装 Ubuntu 24 版本，可以不需要折腾系统环境。

### 1. 脚本说明

这软件好用是挺好用，但它的源都在 Github 上，很多伙伴在执行官网脚本 `curl -fsSL https://opencode.ai/install | bash` 是安装不上的。所以，小傅哥做了一个对应的脚本，方便大家更加简化的安装使用。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-02.png" width="350px"/>
</div>

- 脚本（gitcode）：[https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install)
- 脚本（github）：[https://github.com/fuzhengwei/xfg-dev-tech-docker-install](https://github.com/fuzhengwei/xfg-dev-tech-docker-install)

### 2. 脚本下载

```java
git clone https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install.git
```

- 你可以通过命令的方式把脚本拉取到本地电脑或者云服务器上。

### 3. 脚本授权

```java
find . -name "*.sh" -type f -exec chmod +x {} \;
```

- 全部授权

```java
chmod +x terminal.sh
```

- 指定授权

### 4. 执行安装

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-03.png" width="650px"/>
</div>

```java
./terminal.sh
```

- 执行安装时，选择1，opencode code，这个是比较推荐的。
- 无论是 Windows、Mac、Linux 都可以使用这个脚本进行安装，我已经做好了对应的脚本。
- 安装完成后，需要输入 `opencode` 之后 Enter（回车）进入到系统中。如果提示 opencode 不是有效的命令，可以检查是否安装过程中有个提示 `source .../bashrc` 可以自行执行刷新。

## 三、软件配置

### 1. 命令使用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-04.png" width="650px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-05.png" width="650px"/>
</div>

- `/init` - 创建/更新 Agents.md"
- `/review` - 检查变化"
- `/new` - 创建新的会话"
- `/models` - 选择模型"
- `/agents` - 智能体方式"
- `/session` - 会话列表"
- `/status` - 查看状态"
- `/mcp` - 选择mcp服务"
- `/theme` - 选择主题"
- `/editor` - 编辑"
- `/connect` - 链接模型提供者"
- `/help` - 帮助"
- `/commands` - 命令"
- `/exit` - 调试模式"

> 这些可能会随着版本更新而调整，你可以依次尝试下。

### 2. 配置模型（自定义 - 可选）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-06.png" width="350px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-07.png" width="650px"/>
</div>

```java
{
    "$schema": "https://opencode.ai/config.json",
    "provider": {
        "my-model-openai": {
            "npm": "@ai-sdk/openai-compatible",
            "name": "OpenAPI",
            "options": {
                "apiKey": "你的apikey",
                "baseURL": "https://你的baseURL/v1"
            },
            "models": {
                "gpt-4.1": {
                    "name": "gpt-4.1"
                }
            }
        },
        "my-model-glm": {
            "npm": "@ai-sdk/openai-compatible",
            "name": "GLMAPI",
            "options": {
                "apiKey": "你的apikey",
                "baseURL": "https://open.bigmodel.cn/api/paas/v4"
            },
            "models": {
                "glm-4.7": {
                    "name": "glm-4.7"
                }
            }
        }
    },
    "model": "my-model-openai/gpt-4.1"
}
```

- 如果你想自己更换下模型，比如使用 openai 的或则 claude 的，那么需要你在脚本下的 terminal/opencode.json 进行更换，之后执行 `./opencode.json.sh` 进行创建。
- 如果先执行了 ``./opencode.json.sh`` 之后想更换配置的模型，则可以通过 vim 命令，编辑 `/root/.config/opencode/opencode.json`
- 其他的还有一些像是 mcp 的配置，可以参考官网（避免调整了配置错），[https://opencode.ai/docs/mcp-servers/](https://opencode.ai/docs/mcp-servers/)


## 三、软件使用

### 1. Linux

#### 1.1 构建项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-08.png" width="650px"/>
</div>

#### 1.2 安装软件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-09.png" width="650px"/>
</div>

#### 1.3 巡检系统

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-10.png" width="650px"/>
</div>

#### 1.4 编写文件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-11.png" width="650px"/>
</div>

>通过命令操作云服务器是非常便捷的，尤其是很多小白伙伴，有了这个可以说是如小白虎添翼！打开思路，你可以在更多地方使用上，尤其哪些环境安装都困难的伙伴。

### 2. Mac/Windows + IntelliJ IDEA

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-12.png" width="650px"/>
</div>

- 在本地电脑，除了可以像 Linux 举例那种安装和检查各类软件，也可以直接在 IntelliJ IDEA 开启，之后管理你的项目。
- 尤其是很多伙伴，拿到一个项目，不知道里面都是什么，也不清楚脚本能干啥，那你都可以使用 opencode 帮你解决。

### 3. IPad Pro

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-13.png" width="450px"/>
</div>

虽然 IPad Pro 没啥开发类软件，但如果你使用的是云服务器、Nas等，这些软件里安装 opencode，那么你也可以在 IPad Pro 安装 [termius.com](https://termius.com/) SSH 工具，通过 SSH 工具操作部署了 opencode 的 Linux 系统。

现在日常出门，带着 IPad Pro 也是可以处理一些小的开发的维护的，非常方便。IPad Pro + Nas 嘎嘎舒服！

---

### Md Ai Draw.Io (`docs/md/ai/draw.io.md`)

---
title: draw.io + ai agent
lock: need
---

# draw.io + ai Agent，确实打开新思路

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115652731865787&bvid=BV13ZSaBqE9G&cid=34460795162&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

又到年底了，又要必不可少的开始画图做PPT述职啦 😂，述职的好坏和年终奖都有可能挂钩！这对天天写代码大部分的程序员👨🏻‍💻来说是一件非常头疼的事，但好在这次可以使用个**神器**！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/chatgpt/openai-01.jpg" width="150px"/>
</div>

**Ai Agent 会结合到各个场景！**

可以想象，将来我们使用的各种工具，都会很方便的以标准的协议方式结合到 AI Agent 智能体。这就像小傅哥，25年，年初开始做 Ai Agent 时，对一个智能体的执行过程，是需要自己进行分析，设计，实现的（`那时候我就在讲，Agent 也会出标准框架`）。到了年中的时候 Google ADK 除了 0.1.0 最初的版本，年尾发布了 0.4.0，这个框架提供了构建智能体的最基本框架，可以整合 Spring AI、Langchain4j 快速构建智能体。

>Spring AI、Langchain4j 提供的是 AI 封装能力，Google ADK 提供的是 Agent 执行能力（并行、循环、串行）的组装和使用。

未来（甚至不会太久），各个软件与 Ai Agent 的对接会变得非常容易，你手里用到的各项软件，都可以很方便的添加上智能体的能力。就像，我们现在用到的 `trae.ai`、`Cursor`，在以后 Ai Agent 基础能力成熟后，在结合 `Visual Studio Code` 给出软件对接标准协议，那么任何一个人都可以快速的搭建出一个智能体编码工具。除此之外，其他的软件也都会逐步提供出这样的能力。

扩展的思路分析完毕，小傅哥这次先带着大家了解下，draw.io 是怎么与 Ai 结合使用的。

>🧧 文末提供了小傅哥所有编程实战项目获取方式，一次加入即可获得19个已完结的和本次新开展的。

## 一、关于 draw.io

draw.io 是一个用于绘制通用图表的 JavaScript 客户端编辑器。

官网：[https://www.drawio.com/](https://www.drawio.com/)
代码：[https://github.com/jgraph/drawio](https://github.com/jgraph/drawio)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-01.png" width="950px"/>
</div>

我所有的这类的绘图，都来自于使用 draw.io 完成（[bugstack.cn](https://bugstack.cn) 还有很多绘图）。它可以下载到本地使用，也可以在网页使用。如果你是开发人员，还可以使用它的开发组件引入到自己的程序中进行使用。也正因如此，有了 Ai Agent 能力的结合，一种是通过 MCP，另外一种是直接通过扩展功能，直接在 draw.io 二开上完成。接下来小傅哥会分别介绍这两种方式以及使用。

## 二、MCP 方式对接

MCP（Model Context Protocol）是用于解决 AI 与服务接口通信的标准模型上下文协议，该协议通过标准化通信方式，使AI应用程序能够访问和使用实时数据、执行操作，从而克服了模型训练数据的局限性。 你可以将MCP想象成AI应用程序的“USB-C接口”，它提供了一个标准化的方法，让AI模型能够连接各种外部资源。

**Draw.io Model Context Protocol (MCP) Server**，就是基于此协议实现的对接 Draw.io 的 MCP 服务。我们可以使用这样一套服务，把 AI 与 Draw.io 建立起使用链接。

源码：[https://github.com/lgazo/drawio-mcp-server](https://github.com/lgazo/drawio-mcp-server)

### 1. 插件安装

- 谷歌浏览器：[https://chromewebstore.google.com/detail/drawio-mcp-extension/okdbbjbbccdhhfaefmcmekalmmdjjide](https://chromewebstore.google.com/detail/drawio-mcp-extension/okdbbjbbccdhhfaefmcmekalmmdjjide)
- 火狐浏览器：[https://addons.mozilla.org/en-US/firefox/addon/drawio-mcp-extension/](https://addons.mozilla.org/en-US/firefox/addon/drawio-mcp-extension/)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-02.png" width="650px"/>
</div>

安装完成后，可以看到这样一个小插件（右侧插件文件里可以点击让常驻浏览器），之后后面可以等着使用（继续下面的步骤）。

### 2. 配置服务

```java
{
	"mcpServers": {
		"drawio": {
			"command": "npx",
			"args": [
			  "-y",
        "drawio-mcp-server"
			]
		}
	}
}
```

#### 2.1 trae.ai - 也可以其他的

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-03.png" width="650px"/>
</div>

#### 2.2 spring ai

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-04.png" width="650px"/>
</div>

### 3. 使用服务

首先打开：[https://app.diagrams.net/#](https://app.diagrams.net/)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-05.png" width="950px"/>
</div>

- 对接上之后，你就可以在右侧提问了。之后他就可以实时的出设计图。`受限于MCP服务对接，它不是在 Draw.io 上扩展，会缺少一些交互和判断，画图有时候会有重叠。`
- 不过，这个方式的好处是，你可以结合自己的代码，拖进去，让它直接出架构图、流程图、模型图等。之后在自己做一些调整。

## 三、软件方式使用

现在 Github 上有很多基于 Draw.io 的二次开发，结合了 Ai 的能力，这里小傅哥找到一个做这块功能比较早的，next-ai-draw-io 来演示给大家。感兴趣的伙伴，还可以结合代码做二次开发。

这是一个基于 Next.js 的 Web 应用程序，它将 AI 功能与 draw.io 图表集成在一起。该应用程序允许您通过自然语言命令和 AI 辅助可视化来创建、修改和增强图表。

### 1. 代码下载

代码：[https://github.com/DayuanJiang/next-ai-draw-io](https://github.com/DayuanJiang/next-ai-draw-io)

```java
git clone https://github.com/DayuanJiang/next-ai-draw-io.git
```

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-06.png" width="950px"/>
</div>

下载代码后，注意修改配置文件。

### 2. 启动工程

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-07.png" width="650px"/>
</div>

- 进入 package.json 点击绿色箭头执行启动。

### 3. 访问项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-08.png" width="950px"/>
</div>

- 访问 http://localhost:6002 这样你就可以提问来让它绘制图了。这个效果还不错。

---

### Md Ai Github Models (`docs/md/ai/github-models.md`)

---
title: Github Models
lock: need
---

# Github Models（AI接口），申请使用教程

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

现在做 AI 应用开发的小伙伴越来越多了，随之而来的是对 LLM 大模型接口的使用依赖。一般的模型，可能会让程序出现幻觉。而高质量的模型，大部分是需要付费，比如 `openai/gpt-5`、`azureml-xai/grok3`、`azureml/Phi-4` 等。**那怎么办！？🤔**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-springcloud-feign-01.gif" width="150px"/>
</div>

这些免费的不错的大模型（LLM），也都是有对应的频次和最大出入/输出token的限制。虽然不会让咱们玩命的调用测试。但在程序开发初期，对于单个功能的验证还是非常方便的。接下来，小傅哥就给大家演示下，关于 Github 免费提供的大模型如何配置使用。

## 一、模型说明

### 1. 官网地址

官网：[https://github.com/marketplace?type=models](https://github.com/marketplace?type=models)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-01.png" width="750px"/>
</div>

在 Github marketplace 下提供了非常多的免费的 LLM 使用，gpt-5、gpt-4.1 都是有的，具备完整的测试功能。有时候还会新增加其他模型。

### 2. 频次限制

地址：[https://docs.github.com/en/github-models/use-github-models/prototyping-with-ai-models#rate-limits](https://docs.github.com/en/github-models/use-github-models/prototyping-with-ai-models#rate-limits)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-02.png" width="750px"/>
</div>

- 每日150次、每分钟15次，每次token，8000进、4000出。对于单个模型的验证是没问题的，不过对于复杂的 ai agent 智能体是跑不动的。所以，这块测试的话，要分开验证。之后对于全流程的，在购买 api 进行测试即可。
- 如果小伙伴还觉得，每分钟15次，有点不够干的，那你可以弄10个账号，通过 nginx 负载下，这样基本每分钟150次，一天1500次还是很够用的。

## 二、模型使用

### 1. 测试工程

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-06.png" width="650px"/>
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-github-models](https://github.com/fuzhengwei/xfg-dev-tech-github-models)
- 说明：这里小傅哥准备了一套基于 Spring AI 的测试工程，来验证 Github LLM 的使用。你可以下载后，替换 token/apikey 即可调用验证。
- 环境：jdk 17、maven 3.8.x、spring ai 1.1.0

### 2. 对接申请

#### 2.1 申请token

地址：https://github.com/settings/tokens/new

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-03.png" width="750px"/>
</div>

- 在 Tokens 下，添加 Note 描述和过期时间，完事后不用加任何其他权限，拉到最后设置点击 `Generate token` 生成令牌即可。
- 生成后复制你的 Token，复制后关闭就看不见了。只有删除和创建新的。

#### 2.2 查看curl（api）

地址：[https://github.com/marketplace/models/azure-openai/gpt-4-1/playground](https://github.com/marketplace/models/azure-openai/gpt-4-1/playground)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-04.png" width="750px"/>
</div>

在左侧你可以选择需要使用的模型，之后进行对话验证。之后，在右侧有一个 `Use this model` 这里可以获得模型 API 请求信息。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-05.png" width="750px"/>
</div>

你现在单独验证 api，在整个程序测试前，要确保你的 api 是可用的。

### 3. 测试验证

```java
public class ApiTest {

    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Resource resource = new ClassPathResource("dog.png", classLoader);

        OpenAiApi openAiApi = OpenAiApi.builder()
                .baseUrl("https://models.github.ai/inference")
                // apikey 要替换为你的，在 https://github.com/settings/tokens 创建即可。
                .apiKey("ghp_FfiwBkVunYDQyhIwaQSccVw******")
                .completionsPath("/chat/completions")
                .embeddingsPath("/embeddings")
                .build();

        ChatModel chatModel = OpenAiChatModel.builder()
                .openAiApi(openAiApi)
                .defaultOptions(OpenAiChatOptions.builder()
                        .model("openai/gpt-4.1")
                        .build())
                .build();

        // 模型测试，没问题可以识别图片
        ChatResponse response = chatModel.call(new Prompt(
                UserMessage.builder()
                        .text("请描述这张图片的主要内容，并说明图中物品的可能用途。")
                        .media(Media.builder()
                                .mimeType(MimeType.valueOf(MimeTypeUtils.IMAGE_PNG_VALUE))
                                .data(resource)
                                .build())
                        .build()));

        System.out.println("测试结果" + JSON.toJSONString(response));

    }

}
```

```java
测试结果{"metadata":{"empty":false,"id":"chatcmpl-CzHhVYaXPv3HjJ3oKE4YKPamPQRQB","model":"gpt-4.1-2025-04-14","rateLimit":{"requestsLimit":1000,"requestsRemaining":996,"tokensLimit":1000000,"tokensRemaining":980423},"usage":{"completionTokens":0,"nativeUsage":{},"promptTokens":0,"totalTokens":0}},"result":{"metadata":{"contentFilters":[],"empty":true,"finishReason":"STOP"},"output":{"media":[],"messageType":"ASSISTANT","metadata":{"role":"ASSISTANT","messageType":"ASSISTANT","finishReason":"STOP","refusal":"","index":0,"annotations":[{"$ref":"$.metadata.rateLimit.usage.nativeUsage"}],"id":"chatcmpl-CzHhVYaXPv3HjJ3oKE4YKPamPQRQB"},"text":"这张图片的主要内容是一只卡通风格的小狗。小狗是棕色的，脸部较大，眼睛圆而突出，表情看起来有些疑惑或惊讶，嘴巴微微张开，尾巴翘起。整个形象简洁可爱，线条和颜色运用都比较简单。\n\n**物品的可能用途：**\n1. **图标或表情包**：这种卡通形象常用于聊天软件中的表情包或头像，传达惊讶、困惑等情感。\n2. **儿童绘本或动画角色**：可以作为儿童图书或动画中的形象角色，吸引小朋友的注意力。\n3. **宠物相关宣传设计**：可用于宠物店、宠物产品的宣传海报、包装或logo，增加亲和力。\n4. **教育材料**：在教学课件或教育类APP中，用于引导、示范或者增加趣味性。\n\n整体而言，这是一种很常见且可爱的卡通动物形象，主要用于与宠物、儿童或者情感表达相关的领域。","toolCalls":[]}},"results":[{"$ref":"$.metadata.rateLimit.usage.nativeUsage.result"}]}
```

- 这是一段基于 Spring AI 配置 github llm api的使用方式，尤其注意，baseUrl、apiKey、completionsPath、embeddingsPath、openai/gpt-4.1，这些配置信息和你直接使用管的 gpt 配置是有差异的。
- 本案例，是识别图片的用途，你也可以验证其他功能。这样的项目在小傅哥的 [《AI Agent 智能体》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 都有讲解。

## 三、使用拓展

### 1. 部署脚本

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-08.png" width="750px"/>
</div>

- 这是一套 nginx 转发脚本。你需要有自己的域名（各个云服务器厂商都可以购买）以及申请 ssl 后才可以配置使用。
- ssl 可以从 [httpok](https://bugstack.cn/md/road-map/ssl-httpsok.html) 申请使用。地址：[https://bugstack.cn/md/road-map/ssl-httpsok.html](https://bugstack.cn/md/road-map/ssl-httpsok.html)

### 2. 转发说明（nginx）

如果你希望在使用的过程中，让模型是以你之前使用 openai 一样的方式，那么可以配置一套 Nginx 转发；

```java
server {
    listen       80;
    listen  [::]:80;
    server_name  需要配置域名（api.xxx.cn）;

    rewrite ^(.*) https://$server_name$1 permanent;

}

server {
    listen       443 ssl;
    server_name  需要配置域名（api.xxx.cn）;

    ssl_certificate      /etc/nginx/ssl/_.itedus.cn.pem;
    ssl_certificate_key  /etc/nginx/ssl/_.itedus.cn.key;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /v1/ {
        # 去掉路径中的/v1前缀
        rewrite ^/v1/(.*) /$1 break;
        proxy_pass https://models.inference.ai.azure.com;
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

- nginx 的方式是，当访问有 v1/ 路径的时候，在进行路径重写 `rewrite ^/v1/(.*) /$1 break;` 之后转发到 `https://models.inference.ai.azure.com` - `这个也是 gpt 里的一种模型对接地址`
- 转发后，你就可以直接使用模型服务了。

### 3. curl 验证

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-07.png" width="750px"/>
</div>

- 配置转发后，就可以使用 curl_nginx.sh 脚本进行验证了。

好啦，本文到这，你就可以初步使用免费的 LLM 进行一些一些初始功能验证。2025年，ai agent 开始崛起，2026年，必然是 ai agent 爆发的时候。一定要多学习这类实战项目，企业里 spring 是大盘，所以结合 spring ai 做的项目也必然会非常多。

---

### Md Ai Google Adk (`docs/md/ai/google-adk.md`)

---
title: google adk
lock: need
---

# Google Agent ADK，20分钟，帮你搭建一个简单智能体

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

💐 从22年至今，小傅哥已经带着大家做了5个AI类项目，包括；`（22年）问答助手`、`（23年）OpenAI应用（含支付、敏感词过滤）`、`（24年）AI 代码自动评审`、`（25年）Ai Agent 智能体`、`（25年）Ai MCP Gateway 网关`。

这些项目也都是结合这，AI 这一年最新的技术动向和应用方向，而做的设计和落地。所以，每次小傅哥都给大家讲了，接下来 AI 将影响的一些场景，也都陆续的发生了。就像，24年11月发布 MCP 协议后，我给大家说，所有互联网企业都将大量的落地 MCP 服务，并开始 Ai Agent 智能体实现（别看市面有 dify、扣子，各个且用还是要做自己的业务智能体）。

随后，25年年初，小傅哥就带着大家开始了 RAG、MCP、Ai Agent 智能体的开发，并告诉大家，以后 Ai Agent 智能体也会出标准的框架，让开发更加容易。这不，**谷歌的 ADK 就来了**。并且这哥们👬🏻还定义A2A协议。这会让不是那么大型的互联网公司，也会具备 Ai Agent 智能体开发的能力。

接下来的几年，所有的业务项目，都会以 Ai Agent 智能体翻一遍，程序员新增的岗位和工作量仍然会很多。因为在咱们这，你做的越快，你就得做的越多！

>接下来，小傅哥就带着大家做一下 Google ADK 搭建 AI Agent。如果你感兴趣 AI 类项目，还可以在文末获取全部实战项目源码，深度积累此类技术内容。**文末有Google ADK 运行效果，交互式对话智能体，对 ELK 进行巡检分析。**

## 一、官网资料

- 官网：[https://google.github.io/adk-docs/](https://google.github.io/adk-docs/)
- 搭建：[https://google.github.io/adk-docs/get-started/](https://google.github.io/adk-docs/get-started/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-01.png" width="750px">
</div>

- ADK 以轻便化构建 Ai Agent 智能体，解决智能体开发的复杂流程而设计。目前支持 Python、Java、Go 3种语言对应的技术框架。
- 整个文档完整的描述了，智能体的创建和运行、工具的调用（tools、function、mcp）、可观测性以及 A2A 协议等。
- Agent Development Kit (ADK) is designed to empower developers to quickly build, manage, evaluate and deploy AI-powered agents. These quick start guides get you set up and running a simple agent in less than **20 minutes**.

## 二、工程实践

### 1. 前置说明

本次的 Ai Agent 实践，是以 Google ADK 框架为基础，配和 Github [system-prompts-and-models-of-ai-tools](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools) 开源提示词项目中的 claude-code-system-prompt 作为必要描述。来实验，ELK 系统日志智能分析场景。

- API Key：[https://ai.google.dev/gemini-api](https://ai.google.dev/gemini-api) 需要申请开发 API 秘钥，是免费的。
- Docker 环境，本项目部署了一套 ELK 日志服务，基于 Docker 部署，之后对 ELK 模拟写入日志，让 Ai Agent 智能体进行分析。`如果暂时配置不了，可以在测试的时候去掉这部分 mcp 服务`
- `JDK 17+`、`Maven 3.8.x`

### 2. 工程说明

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-02.png" width="950px">
</div>

- 工程地址：[https://github.com/fuzhengwei/xfg-dev-tech-google-adk](https://github.com/fuzhengwei/xfg-dev-tech-google-adk)
- 这是一套引入了 Google ADK 0.1.0 版本的 Agent 最基础智能体测试。如果需要扩展，还要额外增加很多东西，可以参考 [《Ai Agent 智能体项目》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html)

#### 2.1 YML 配置

```java
server:
  port: 8901

# 可申请API秘钥；https://ai.google.dev/gemini-api
google:
  api:
    base-url: https://generativelanguage.googleapis.com
    key: AIzaSyDF6JnvFx7xWEsARS*******可以自己申请免费的
  cloud:
    project: xfg-google-adk

logging:
  level:
    root: info
  config: classpath:logback-spring.xml
```

- 在 `application-dev.yml` 修改你的参数配置，配置你的 Google api key

#### 2.2 ADK 单测

```
/* Detailed source-code truncated for AI context efficiency. */
```

```java
Agent > Hi there! Yes, I'm here to help.  To best assist you, could you tell me what you need help with?  The more information you give me, the better I can understand your request and provide a useful response.
```

- 这是一套最基础的 Ai Agent 智能体 ADK 的测试使用代码。其实它的配置和调用与 Spring AI 框架是有类似之处的，基本上这类框架也都是这样的使用模式。
- LlmAgent 提供了一整套构建智能体的方式，可以设置客户端（Gemini），并设置相关的 baseUrl、apiKey 参数，以及模型和超时时间等。
- InMemoryRunner 的用途是把 Agent 放入一个记忆执行里，让一整个 Session 会话下的执行都被记录下，这样才能记录上下文。
- 之后就是放到响应框架进行之后和拿到最后结果啦。

#### 2.3 Agent 智能体测试

```
/* Detailed source-code truncated for AI context efficiency. */
```

- AutoAgentTest 智能体，配置了两个 mcp，mcp_elk、mcp_filesystem 服务。其实 AI Agent 智能体，都少不了 MCP 服务的加持，这样才能让这个大脑有手脚可以行动起来。
- init 初始化阶段，instruction 配置了对应的智能体提示词，这部分很重要，有点像智能体的神经。[https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Claude%20Code/claude-code-system-prompt.txt](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Claude%20Code/claude-code-system-prompt.txt) - 可以选择这里的提示词配置到智能体进行测试。
- 这部分也可以运行测试，之后会你可以进行提问。注意，如果你没有配置 elk，那么可以删掉 `mcpTools.addAll(mcp_elk());` 代码。
- mcp_filesystem() 配置了，`/Users/fuzhengwei/Desktop` 你需要修改为你的本地的有权限访问的地址。

#### 2.4 Agent 智能体服务

有了前面的案例测试基础，就可以把服务配置成对应的接口，以及开发个简单的页面进行对接验证了。

##### 2.4.1 服务接口

```java
@Slf4j
@RestController
@RequestMapping("/trigger")
@CrossOrigin(origins = "*")
public class AgentController {

    private final AgentService agentService;

    public AgentController(AgentService agentService) {
        this.agentService = agentService;
    }

    @PostMapping(path = "/session", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public CreateSessionResponse createSession(@RequestBody CreateSessionRequest req) {
        String sessionId = agentService.createOrGetSession(req.getUserId());
        log.info("创建会话ID:{}", sessionId);
        return new CreateSessionResponse(sessionId);
    }

    @PostMapping(path = "/chat", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ChatResponse chat(@RequestBody ChatRequest req) {
        String sessionId = req.getSessionId();
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = agentService.createOrGetSession(req.getUserId());
        }
        log.info("使用会话ID:{}", sessionId);
        List<String> outputs = agentService.chat(req.getUserId(), sessionId, req.getMessage());
        return new ChatResponse(sessionId, String.join("\n", outputs));
    }
}
```

- 这里就是把单测的服务，包装成接口。详细的部分可以直接看工程代码。

##### 2.4.2 页面对接

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-03.png" width="950px">
</div>

- 把服务端的接口对接到页面。

## 三、功能测试

### 1. 部署 elk 日志服务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-04.png" width="950px">
</div>

- 整个 Ai Agent 案例，配置了 ELK 作为日志分析的基础，所以最好配置下。
- 这里也有云服务器的部署操作，也可以参考教程来部署。教程：[https://bugstack.cn/md/road-map/docker-install.html](https://bugstack.cn/md/road-map/docker-install.html)
- 注意配置完成后，要执行 `elk-blacklist-data.sh` 模拟的写入进去一些日志，这样才能用于分析使用。

### 2. 启动服务访问页面

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-05.png" width="700px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-06.png" width="700px">
</div>

- 以上演示了，使用 Ai Agent 进行 ELK 日志分析，通过对话可以看到，最终我们可以拿到系统的日志数据。
- 你还可以尝试配置其他的 MCP 服务，之后验证各种场景功能。担任如果你希望更细化的做 Ai Agent，还是要看下 [《Ai Agent 智能体项目》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 这样可以更细腻的做出这样的系统，以及对应的可视化编排操作。

---

### Md Ai Introduction (`docs/md/ai/introduction.md`)

---
title: 初识智能体
lock: need
---

# 📚《从零理解智能体（+八股）》第1篇，认识智能体，从过去到现在

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

**我不是上车 AI 赛道，而是 AI 赛道的开车人！** 自 2022 年底，以 OpenAI 正式对外发布 ChatGPT 大语言模型 LLM（Large Language Model）开始，小傅哥便随时开启了 AI 应用开发的`”班车“`，先是最早发布了 AI 结合场景应用的问答助手，后是基于 AI 接口实现 SDK 做 OpenAI 应用，再往后逐步跟随最新 AI 技术（规范、模型、组件）实现相关的各类智能体服务。再到最近，以个人开发者发布了一款 AI IDE 工具 WaLiCode - [https://walicode.xiaofuge.cn](https://walicode.xiaofuge.cn) —— AI 让我走向了全栈开发！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/ai-rag-knowledge/ai-rag-knowledge-0-00.png" width="150px"/>
</div>

**AI 时代，只要你学的足够慢，那你就不用学了！**

AI 的发展非常快，快到什么德行！如果一个`技术`/`服务`/`软件`，你还没来得及学，那么几周后，可能就淘汰换新品了。所以学的都够慢，很多东西就不用学了！

然而，事情的本质并不是这样。那些所谓的换新，眼花缭乱的 AI Agent 服务，都只是上层产品形态，对于底层的核心内容，协议、标准、组件，都没有变，而是逐步的开枝散叶。如果当你从一开始，就跟着小傅哥体验 API + 业务，手搓 AI SDK，在实现 AI Agent 服务，那么这个阶段，你就是一个标准的 AI 应用开发工程师，毛线的焦虑都不会有！

但没办法，有些伙伴就是错过了这一班车，都已经到了市面上大量出现 AI Agent 应用开发岗，到了公司倒逼着程序员了解 AI，使用 AI，才后知后觉的开始准备学习。然后被市面上的大量资料、产品、服务，带着节奏东跑一下，西跑一下。碎片化的知识（~~还包括用AI窜出来的~~），给人搞的身心疲惫。

所以，他来了！**《从零理解智能体（+八股）》** 从零，即是从本质出发，从第一性原理上手，从实践中学习。本套内容会系列的为大家补全关于`智能体`的相关知识，让小白伙伴跟着学习后对`智能体`也能有个清楚的认知。希望这次别错过这趟车，免费的班车 🚌！

>💐 文末还有相关智能体实战项目，一整套内容从22年 AI 发展到至今，全部都有代表性实战项目。通过实战项目学习，也可以很好的掌握智能体技术，成为 AI 应用开发工程师。

## 一、什么是智能体

简单来说，AI智能体（Agent）就是一个能够感知环境、做出决策并执行行动的智能系统。它就像一个有"大脑"和"手脚"的助手，可以帮你完成各种任务。

**但更直白一些来讲，智能体是这样（我们以发展迭代视角来看）；**

2022年，OpenAI GPT 横空出世，我们得到了一个牛逼的网页对话服务。它像是一个超级大脑，可以为我们解答各类问题，包括像是程序员遇到代码错误，也可以询问后给出一些正确的编码方式，之后我们在复制到工厂里运行验证到使用。这一时刻，大家普遍把 AI 定位成比百度更牛的搜索引擎。

2023年，各大 LLM 大语言模型爆发，也都开始提供 API（http）接口对接协议。这一年，我们把 AI 通过 Github 外挂程序接入到微信群（~~对接一次￥500~~），也接入公众号，还接入到各个网站以及网页分析，网页翻译等场景。因为直接访问 gpt 困难，因此做一套套壳的服务，成了变现入口。

```java
curl https://api.openai.com/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-DEOKLWYTQ0Lim9******" -d '{
  "model": "gpt-3.5",
  "messages": [
    {
      "role": "user",
      "content": "写个冒泡排序"
    }
  ]
}'
```

> API 协议就是这样，一个简单的 http 接口，来调用模型。为了更加方便的调用，后来各个厂家为自己的模型封装了 SDK 组件。这类组件小傅哥也带着实现了好几个。举例；[https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java-v2.html](https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java-v2.html)

2024年，以前的 AI 对话，只是问啥说啥，还可以告诉你怎么做，但它不去做。为了让它可以去做，我们开始设定 AI 对话中返回的格式结构，比如一个标准的 json 结构，还要告诉它不要解释任何信息，只给我返回这样一个结构，并直接告诉我结果。这一阶段，开始有苗头，AI 能做一些事了。因为返回的结构化 json，就可以被程序翻译识别，转而调用服务接口，但幻觉严重，实际使用效果还是有点差。不过这样的操作方式，也给 OpenAI 带来了新的思路，MCP 标准上下文协议于24年发布，它可以让我们以标准的协议方式，使用 AI 调用服务接口。之后就炸了！因为这相当于正式的给 AI 装上了四肢，它可以真的帮你干活了。百度搜索、谷歌地图、淘宝支付，也包括你公司的业务项目都能提供出来 MCP 协议接口服务，这个有脑子的 AI + 各种能力的服务，让各个互联网公司不得不重视 AI 的应用开发。

2025年，这是 AI Agent 智能体应用类项目爆发的一年，最有代表性的是 AI IDE 代码开发工具，Claude Code 可以说是玩命的干这个方向，把模型能力和工具能力都拉到爆。~~其他各个厂商，也都开始跟进开发 AI IDE 工具，之后大公司卖 coding/token plan，个人卖中转站。~~ 海外这些 AI 大厂商，为了能让 LLM 更准确的执行用户意图，发布了 skills 技能书（这些细节后续章节再分享），把一套套执行流程的标准做成技能（类似 sop 标准），这样 LLM 可以不需要那么准确的提示词（一次次重复写），就能很好的执行标准流程（画个时序图、按照DDD重构代码等）。当然，也有离职的好哥们被蒸馏成了 skills，虽然他人走了，他的灵魂永远留在了岗位。

2026年，开年之后最为炸裂的是 OpenClaw 养虾，把 Mac Mini 都干涨价了，上门安装 OpenClaw 也成了生意。OpenClaw 的玩法开发了一套电脑端网关，说白了也就是让 LLM 对接的不只是 mcp、skills，而是对接了硬件设备，让 LLM 可以直接像人一样操作电脑。其实在这东西之前，25年到26年，还有智谱发布的 autophone 通过 LLM 控制手机。不过手机的护城河目前太高，安全级别也很高。短时间还不太会各处开花。

---

综上，这是22年到26年的关于 LLM 大语言模型以应用视角下的发展路径。这里我画过一张图，可以参考；

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-02.png" width="950px">
</div>

整个 AI 发展的诉求是这样；

- 因为，有 LLM 大语言模型对话诉求，所以基于机器学习，大规模的训练数据。
- 因为，有 LLM 对话可以调用外部服务的诉求，所以设计了 function 函数和 mcp 模型上下文协议。
- 因为，有 LLM 对话要像人一样可以规划、执行、检查诉求，所以设计了 agent work flow（ReAct）工作流。
- 因为，有 LLM 对话要有历史记忆诉求，所以设计了各类的 memory 记忆上下文，这个阶段还把 rag 向量知识库，作为存储源过。
- 因为，有 LLM 对同类智能体的分离诉求，所以设计了 a2a 协议，可以本地智能体调用其他智能体。
- 因为，有 LLM 对话不能每次都写一堆提示词说明情况，有了 skills 技能，把人的各类标准行为”蒸馏“成模块包，让 ai 应用使用，复用能力。
- 因为，有 LLM 对话编码过程中，还会有”惊喜“，每次执行的不一样。所以有了 [spec](https://github.com/github/spec-kit) 各类规约的限定，让 ai 从以前的随意搞，到现在的有规划和路径的搞。

llm、rag、function、mcp、skills、agent work flow（ReAct）、memory、a2a、spec...，他们总是在研究，怎么让 ai 更可靠。也一直想办法让 ai 像个人一样工作。你一次干不了的活，就让你记忆（短期/长期/工作），还让你有规划（拆解/执行/反思），再交给你干这个活的经验（skills 复刻能力），怕你干跑偏在你规约（spec-kit）。还干不好，没关系。ai 发展这么快，总会让你把活干明白。

## 二、了解发展历史

如果说过去几年是AI行业的“大航海时代”，那么如今我们已正式步入“大建构时代”。在这场重塑人类生产力的工业革命中，谷歌、OpenAI与Anthropic不再仅仅是技术路径的角逐者，更是三种截然不同的AI文明的构建者。他们共同推动了AI从“文本生成器”向“数字世界执行者”的历史性跨越。

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-introduction-01.png" width="950px">
</div>

**Google：全栈生态的守望者与多模态的践行者**

作为Transformer架构的缔造者，谷歌曾一度在生成式浪潮中显得庞大而迟缓。但在最新的现实中，谷歌凭借其无可比拟的“全栈底座”（TPU算力矩阵 + Android/Chrome终端生态 + 搜索数据）打出了反击战。其演进路线不再执着于单点突破，而是强调**“无处不在”与“原生多模态”**。通过Gemini系列，谷歌试图将AI化作水和电，无缝接入全球数十亿台设备中，实现跨越文本、视觉、音频的实时感知与交互。

**OpenAI：从“规模神话”到“系统2推理”的破壁人**

OpenAI曾用海量数据和算力验证了Scaling Law，推开了生成式AI的大门。然而，随着数据墙的逼近，OpenAI的最新锚点已从“生成（Generation）”转向了**“深度推理（Reasoning）”**（如o1系列模型）。通过引入强化学习与“测试时计算（Test-time Compute）”，OpenAI正在让AI从“凭直觉说话”进化到“思考后再回答”。他们依然是AGI（通用人工智能）最激进的冲锋者，试图在数学、编程和科学探索领域率先实现真正的机器逻辑。

**Anthropic：以“安全宪法”重塑企业级信任的实干家**

最初被视为OpenAI“保守派克隆体”的Anthropic，反而在商业落地中走出了最坚实的一步。其“宪法AI（Constitutional AI）”不仅仅是安全制衡的工具，更意外地造就了Claude系列在长文本处理、复杂代码编写和指令遵循上的惊人稳定性。Anthropic放弃了花哨的C端炒作，精准切入程序员与企业工作流（如Artifacts交互机制），证明了**“可控性与安全”本身就是最强大的生产力**。

无论是谷歌的设备级渗透、OpenAI的极致推理，还是Anthropic的可靠工作流，三家的路径正在收敛于同一个终局：**打造能在复杂现实世界中自主解决问题的智能体。** 这不再是一个纯粹的实验室科学问题，而是一场关乎算力调度、能源争夺、终端重构以及人类社会伦理适应的系统级战争。Transformer播下的种子，经过Scaling Law的催化，正在安全的护栏内，长出接管数字世界的神经元。

## 三、智能体的用途

智能体目前正处于从“只会说”到“能去做”的跨越期，从过去能做什么，到现在还有什么不能做的阶段。通过 AI MCP Gateway 解决了从应用服务到智能体的衔接，使用 Skills 提供了各类角色技能，叠加 Spec-Kit 做规约处置，我们让一个智能体的所应用场景变得越来也广泛和可靠了。

所以，当下阶段各类场景，都会被智能体逐步接入（举例）；

<div align="center">
    <img src="https://bugstack.cn/images/article/ai/ai-introduction-02.png" width="650px">
</div>

## 四、开发所需框架

不少伙伴被市面信息弄的很焦虑，本身学习 Java 的是不还要学习下 Python、Go 的 Agent 开发。但其实，企业里各个业务线是有所不同的，因此使用的语言也不一样。每一个语言，都有非常庞大的知识体系，来满足这个语言下各类场景的开发诉求。如果你是做 Java，其实优先把 Java 相关的智能体技术做好就可以。

1. 对于业务类项目，java 有庞大的市场，如美团、京东、阿里、饿了么、滴滴等。这些业务会大量的引入 ai 进行提效，如客服、巡检、日志分析、运营等。
2. 因为这些业务本身就是使用 java，背靠 spring，所以很多公司天然的选择了 spring ai 框架进行开发以及二次扩展（阿里的 spring ai）。所以学习 spring ai 是完全没问题的，包括谷歌，也做了 java 的 agent 框架。（星球ai agent脚手架课程，使用 spring ai/langchain4j + google adk - mcp、skills、a2a、agent work flow等，内容很全面）
3. 不同语言应对场景不同，如 py 更多面向基础、数据、量化等。java ai 更多面向业务，而业务岗位也是最多的。

其实，你一套东西搞透彻，很多东西也就自然而然的可以理解和上手了！

### 1. 🤖 Python 生态

| 框架             | 官网                                      | 特点                                                    |
| :--------------- | :---------------------------------------- | :------------------------------------------------------ |
| **LangChain**    | https://docs.langchain.com                | 最流行的 LLM 应用编排框架，模块化，支持 RAG/Agent/Chain |
| **LlamaIndex**   | https://www.llamaindex.ai                 | 专注数据连接与 RAG，文档索引优化能力强                  |
| **LangGraph**    | https://langchain-ai.github.io/langgraph/ | LangChain 团队出品，图形化工作流编排                    |
| **CrewAI**       | https://www.crewai.com                    | 多 Agent 协作框架，角色化编排，易上手                   |
| **AutoGen**      | https://microsoft.github.io/autogen/      | 微软开源，多 Agent 对话协作                             |
| **Dify**         | https://dify.ai                           | 开源 LLM 应用开发平台，低代码/零代码                    |
| **Coze（扣子）** | https://www.coze.cn                       | 字节跳动出品，Bot 编排平台                              |

### 2. ☕ Java / JVM 生态

| 框架                  | 官网                                         | 特点                                  |
| :-------------------- | :------------------------------------------- | :------------------------------------ |
| **Spring AI**         | https://spring.io/projects/spring-ai         | Spring 官方出品，统一 API 集成多模型  |
| **Spring AI Alibaba** | https://github.com/alibaba/spring-ai-alibaba | 阿里云开源，基于 Spring AI + 通义系列 |
| **LangChain4j**       | https://docs.langchain4j.dev                 | LangChain 的 Java 实现版              |

### 3. Agent 开发工具包

| 框架                  | 官网                                                         | 特点                                                         |
| :-------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| **Google ADK**        | https://adk.dev/                                             | Google 智能体开发工具包，图形化 Agent 构建。非常好用！支持多套语言 Java、JS、Python、Go |
| **OpenAI Agents SDK** | https://openai.github.io/openai-agents-python/               | OpenAI 官方 Agent SDK                                        |
| **LlamaIndex Agents** | https://docs.llamaindex.ai/en/latest/module_guides/deploying/agents/ | LlamaIndex 的 Agent 模块                                     |

```java
public class ChatGPTClient {
    
    private final String apiKey = "sk-xxxxxxxxxxxxxxxxxxxx";
    
    public String chat(String message) {
        // 1. 构建请求
        String requestBody = JSON.toJSONString(Map.of(
            "model", "gpt-3.5-turbo",
            "messages", Arrays.asList(
                Map.of("role", "user", "content", message)
            ),
            "temperature", 0.7
        ));
        
        // 2. 发送HTTP请求
        try {
            HttpResponse<String> response = HttpClient.newHttpClient()
                .send(HttpRequest.newBuilder()
                    .uri(URI.create("https://api.openai.com/v1/chat/completions"))
                    .header("Authorization", "Bearer " + apiKey)
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                    .build(),
                HttpResponse.BodyHandlers.ofString());
            
            // 3. 解析响应
            JSONObject json = JSON.parseObject(response.body());
            return json.getJSONArray("choices")
                       .getJSONObject(0)
                       .getJSONObject("message")
                       .getString("content");
        } catch (Exception e) {
            throw new RuntimeException("调用OpenAI接口失败", e);
        }
    }
}
```

>除以上之外，每个公司，还有自己的智能体开发框架。所以对你来说，你主要一套搞透彻，进入公司就可以做其他的内容。因为说到底，你还是在使用统一的 api，只是上层被不同语言封装了，之后为你构建智能体提供了方便。项目举例；[https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html)

## 五、我们正面临的

从2022年ChatGPT发布到现在，AI智能体已经走过了从简单对话到自主执行的发展历程。作为研发工程师，我们正处在一个非常有意思的时代，既见证着技术的快速变革，也有机会参与其中。

智能体不是要替代人类，而是要成为我们的得力助手。理解它的发展脉络，掌握它的核心技术，能让我们在这个AI时代更好地发挥自己的价值。

但要想更好的驾驭 AI，一定是深耕自己的技术，否则会让你觉得 AI 虽然能帮忙，但也会让你更忙。

>后续涉及各个细节的技术类章节，会附带的提供一些面试问题。

---

### Md Ai Kimi (`docs/md/ai/kimi.md`)

# kimi

作者：小傅哥
博客：[https://bugstack.cn](https://bugstack.cn/)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

你现在，在用什么 AI IDE/Cli + LLM 组合？可靠不？🤔

费劲下载 `Claude Code` 是因为它模型够强，乐意折腾 `Codex` 是想着它功能完善。却不知两款工具暗藏风险陷阱，随时可以扒掉你的裤衩🩲，回传服务器进行安全检测🤨。结果就是，封号、封号、封号！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/walicode/walicode-introduce-01.gif" width="150px"/>
</div>

Claude Code 本地静默执行时区校验、中转域名黑名单双重检测，依托无痕 Unicode 隐写术隐秘嵌入用户属地、代理、机构特征，零流量痕迹静默上报建档、伺机封禁，申诉邮件还暗藏追踪像素窃取真实 IP；而 Codex 依托云端多维风控体系，通过网络 IP 溯源、代理网关筛查、账号行为建模、批量调用异常检测综合判定风险，精准拦截非合规访问，二者一靠本地隐写埋标记、一靠云端行为打分风控，全程静默取证、针对性封号，让国内开发者防不胜防。

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-01.png" width="850px"/>
</div>

>这也就是为什么你的 claude code、codex 用着、用着，就封号了的根本原因。

就这么封号，我都想过，那我买一台黄仁勋（dgx spark）部署个 `qwen3.6:35b` 再配合个其他的 AI IDE/CLI 不就解决封号了吗，还 Token 自由了？但我告诉你个真相吧，这压根不可能！好几万花出去，也写不出来高质量代码！

**为啥呢？**

这个 [walicode.xiaofuge.cn](https://walicode.xiaofuge.cn/) 是我的 AI IDE 作品，有几万个用户安装使用。那我从一个 AI IDE 开发工程师的角度给你讲为啥。一次用户诉求处理，需要组装提示工程，涵盖了；分层缓存（命中如 DeepSeek 规则）、角色提取、模板注入（tool、mcp、skills、cli）、结构约束、多轮压缩等，这些东西加一块在结合复杂的代码工程代码，到这第一步，上下文的数量就已经让你自己部署的 LLM 吃不消了。

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-04.png" width="750px"/>
</div>

这还没完，紧接着，LLM 要根据用户的请求信息，准确的返回可执行的工具指令，如，读取哪些文件，文件路径是什么。写入哪些文件，写入内容是什么。复杂场景的 Plan 规划是什么，有没有可靠的步骤拆解。感知、推理、规则、执行、观测，哪一步都不能掉链子，否则就要反复的给 AI 说，`继续`、`不对`、`你没听懂我说的`。因为质量较差的模型，第一步返回的路径，都会错。如，你要的是 `ai-agent-guide/chapters` 有些 LLM 给你返回的是 `ai-aguide/chapters`。这也是我在开发 WaLiCode 的时候，非常多用户，使用的各种模型，反馈的问题。为这些质量较差的模型做非常多的兜底策略，尽量不让用户对着模型大吼 `继续`、`继续` 的时候，内部做一些自动化的处理。

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-03.png" width="150px"/>
</div>

呐，[WaLiCode](https://walicode.xiaofuge.cn/) 我干了4个月+，经过这么长时间的开发和运营，还有这么多用户让我测试的各种模型。也找到了一些好用的组合。如；DeepSeek 的在命中缓存多的情况下，费用不算太高。GLM 5.1/5.2 + Coding Plan 比较划算，Token Plan 大部分扛不住编码多久。

之后，还有最近大家总提的 `Kimi`（月之暗面）给我整上车了 🚌，干了个最高套餐 Kimi Allegro 会员！**真快呀！是真快！**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-02.png" width="150px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-05.png" width="350px"/>
</div>

花点钱，花点！是很快呀，小不溜溜的，就是100到大几百 t/s 的跑，嗖嗖的解决问题，再也不用傻等了。

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-12.png" width="350px"/>
</div>
有爆料，Kimi K3 编码能力可以和 GPT 5.5 持平，稍弱于 Fable 5！不错，可以搞！


>接下来，就教大家怎么购买、怎么配置，以及在复杂的编程场景验证使用效果。反正都是要找 Coding Plan 买，那就搞个模型不差的，速度最快的！

## 订阅 Kimi 套餐🍱

打开 Kimi 官网：[https://www.kimi.com/membership/pricing](https://www.kimi.com/membership/pricing)

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-06.png" width="750px"/>
</div>

Kimi 会员套餐有多种类型额度可以选择，个人比较推荐 79/159 元以上的套餐，对于大部分日常办公，写代码、写文档、做设计，就基本够用了。

如果暂时就是想试试水，可以搞一个月跑跑看。长期使用比较建议选择`按年`会更划算。避免像 GLM 一样，最后抢不到了。

## 获取 API（Key）

控制台：[https://www.kimi.com/code/console](https://www.kimi.com/code/console)

进入后，`+新建 API Key`：

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-07.png" width="750px"/>
</div>
> **注意**：API Key 和你的会员权益是绑定的。会员到期后 Key 不会立刻失效，但调用额度会回落到免费层水平，编码体验会明显下降，到时候再续费就可以了。

| 协议           | Base URL                         | 常用 Endpoint 示例                                |
| :------------- | :------------------------------- | :------------------------------------------------ |
| OpenAI 兼容    | `https://api.kimi.com/coding/v1` | `https://api.kimi.com/coding/v1/chat/completions` |
| Anthropic 兼容 | `https://api.kimi.com/coding/`   | `https://api.kimi.com/coding/v1/messages`         |

```curl
xiaofuge@ZBMac-GV47H1GXD ~ % curl https://api.kimi.com/coding/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-kimi-AIwit*****你的ApiKey" -d '{
  "model": "kimi-for-coding-highspeed",
  "messages": [
    {
      "role": "user",
      "content": "1+1"
    }
  ]
}'

# 测试结果
{"id":"chatcmpl-rotV60lwrnRMoRtQm2NwZhKF","object":"chat.completion","created":1784099022,"model":"kimi-for-coding-highspeed","choices":[{"index":0,"message":{"role":"assistant","content":"1 + 1 = 2","reasoning_content":"The user is asking a simple math question: 1+1. I should answer directly and clearly."},"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":31,"total_tokens":41,"completion_tokens_details":{"reasoning_tokens":22}}}%  
```

两种协议均可使用 `kimi-for-coding`（普通版）与 `kimi-for-coding-highspeed`（高速版）两个模型 ID。在申请到 ApiKey 以后，用 curl 方式验证下。

## WaLiCode 下载&模型配置

进入 WaLiCode 官网，点击下载（windows exe，mac dmg，也支持 安卓/ios）。下载完成之后双击开始安装。

官网地址：[https://walicode.xiaofuge.cn/](https://walicode.xiaofuge.cn/) 

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-08.png" width="750px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-00.png" width="750px"/>
</div>

- 产品功能如图所示，你可以参考后使用。基本这些内容，和市面的各类 AI IDE 的设计也都是类似的，没有什么迁移使用成本。更为友好的地方是，不会乱上传你的数据，也不用费劲折腾配置。
- 下载安装后，就可以按照下面的环境配置进行操作了。一会我们就把 Kimi 给配置到渠道里使用。

>注意，Kimi 支持 CC Switch 配置，之后你就可以继续在 claude code、codex 等软件使用。Kimi 官网也有一款 Kimi Code Cli 也可以安装使用。脚本：curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-09.png" width="450px"/>
</div>

- Base URL：https://api.kimi.com/coding/v1
- 秘钥：https://www.kimi.com/code/console - 创建 ApiKey 复制
- 模型：kimi-for-coding | kimi-for-coding-highspeed 普通版模型和高速版模型

## 开发使用

面向高复杂度、高负载工程研发场景，该模型综合能力可对标 GPT-5.5 并实现等效替代，工程落地表现优异。

1. 架构解析与可视化建模：针对系统架构图解读、绘制任务，可完整保留业务核心链路，精准定位项目核心代码模块并输出结构化代码分析结论，无关键逻辑丢失问题；
2. 大型分布式项目故障根因分析：以 AI MCP 网关分布式业务场景故障为例开展实测，模型可完成全量工程代码通读、链路拆解，输出具备落地可行性的完整排障解决方案；
3. 工程代码生成实现：基于输出的优化 / 修复方案驱动代码开发，可精准产出符合工程规范、适配现有项目技术栈的业务代码；
4. 工程验证与问题闭环：开发交付后支持后端工程全流程问题排查，可独立完成项目编译构建、依赖 Jar 包拉取、功能复现与结果校验，形成完整研发验证闭环。
5. 整个项目开发完成后，还可以直接让 AI 操作上线，运维，压测，这些内容的测试，Kimi 都表现的都非常稳定。

### 1. 架构绘图

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-10.png" width="950px"/>
</div>

### 2. 复杂分析

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-11.png" width="950px"/>
</div>

### 3. 功能实现

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-13.png" width="650px"/>
</div>

### 4. 问题排查

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-14.png" width="750px"/>
</div>

### 5. 项目上线

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/kimi-15.png" width="750px"/>
</div>

## 最后总结

如果你也担心 Claude Code 随时骚操作封号、Codex 使用起来也不那么安全。那么可以试试 WaLiCode 也可以使用 Kimi 官网的 Cli 工具，并配合 Kimi K3.0 不用折腾就可以安心做开发了。

当然 Kimi 也不是必须，GLM、DeepSeek 这2个模型也非常稳定，如果能买到不限速的 Coding Plan 也是不错的。最后，综合使用就好，再配合市面上有时候出来的免费的，组合起来使用，也是美滋滋的。Kimi

---

### Md Ai Openclaw (`docs/md/ai/openclaw.md`)

---
title: OpenClaw
lock: need
---

# 🦞OpenClaw，你是不还没有安装上？这个中文版，可以试试！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=116049177479006&bvid=BV1k2Foz7EMx&cid=35973893805&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

🦞OpenClaw，大龙虾，看着挺复杂，其实一点也不简单。都火成这德行了，但也还是有很多伙伴在安装这一块就挂壁了。想体验呀，咋整？

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-01.gif" width="150px"/>
</div>

**怎么理解 OpenClaw 🦞**

OpenClaw 是一款开源 AI 助手，不到2个月时间 [Github](https://github.com/openclaw/openclaw) 点赞量已经超过 170k Star ⭐️，它的出现为我们提供了更俏的思路使用 LLM 大模型。从24年底，定义了 MCP 协议，25年爆发了 Ai Agent 的落地，随后出现 [GLM AutoPhone](https://bugstack.cn/md/algorithm/model/autoglm-phone-agent.html) 控制手机，现在又来了大龙虾 OpenClaw 控制电脑。

你可以把 OpenClaw 理解为一个从你到电脑设备，需要敲键盘的过程，**设计了一个中间网关层**。你的指令可以通过各类 APP/Web 对话的方式，下发给 OpenClaw 完成电脑的一些列操作。如；`帮我安装个Docker`、`在Docker中部署下Redis`、`告诉我现在运行状况和剩余可用资源`等等操作。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-02.png" width="750px"/>
</div>

综上，这让我们离`数字员工`又近了一步，后续可以拷贝个人工作技能到 skills 编写，如一些高频重复的场景，对现存系统运行的巡检，对运营类数据的排查，对活动经营情况的分析等。都可以被制作为 skills 让 OpenClaw 使用。

接下来，小傅哥就带着大家安装下 OpenClaw + 飞书配置，这套组合还是蛮好用的。

## 一、安装介绍

### 1. 软件

官网：[https://openclaw.ai/](https://openclaw.ai/)
源码：[https://github.com/openclaw/openclaw](https://github.com/openclaw/openclaw)

中文社区：
- [https://clawd.org.cn/](https://clawd.org.cn/) - `新人伙伴比较推荐实用这个，全是中文提示，安装起来更友好。`
- [https://openclaw.qt.cool/](https://openclaw.qt.cool/)
- [https://1panel.cn](https://1panel.cn/)

> 除了官网的 OpenClaw 资源，还有不少中文社区，对 OpenClaw 做了镜像和汉化的处理。安装方式也都一样，小白伙伴也可以体验下，全是中文对小白更友好。另外，这部分汉化是基于 openclaw 源码来做的，如果你有一些预安装诉求，以及汉化或者有自身公司想做些扩展也可以基于源码 fork 来改造。

### 2. 环境

- nodejs 22+ （不少安装包里会提供检测和安装）[https://nodejs.org/zh-cn/download](https://nodejs.org/zh-cn/download)
- 2c4g 云服务器/本地电脑 [https://618.gaga.plus](https://618.gaga.plus) - `推荐买1年送3个月的` + Ubuntu 24 系统。
- 环境初始化脚本 [https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install) - `执行 sudo ./openclaw.sh 会帮你在云服务器安装 nodejs 22+`
- 镜像资源 `--registry https://registry.npmmirror.com` 如使用 `sudo npm install openclaw@latest --registry https://registry.npmmirror.com`

### 3. 资源

- GLM ApiKey：[https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys](https://www.bigmodel.cn/glm-coding?ic=KFLKGANUMO) - 可以换账号新注册下，获取2000万token，可以提前申请好，复制到自己的文档里（你可能会失败好多次，反复使用）。
- 飞书：[https://open.feishu.cn/app](https://open.feishu.cn/app) - `企业自建应用（下载个桌面版更好用）`，先发布一次（拿到App ID、App Secret）让 OpenClaw 对接上，之后再飞书机器人配置上**事件配置**，之后在发布一次应用。这样就建立起链接了，下文教程有详细处理过程。

## 二、部署介绍

### 1. 部署流程

OpenClaw 的安装过程中，会涉及一些列命令的使用，我把这些放到一个图里，方便大家理解；

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-03.png" width="750px"/>
</div>

- 首先，关于安装可以使用 curl 向导式一次安装，也可以使用 npm 安装软件后，在启动配置向导。在 [xfg-dev-tech-docker-install](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install) 一键安装脚本中，提供了 `sudo ./openclaw.sh` 安装脚本，附带的会帮助你完成 nodejs 22+ 的检测和安装，以及飞书组件的提示，会简化一些你的操作。
- 然后，在执行 `sudo openclaw onboard` 运行向导后，会告诉你这个软件的安全提示，你可以通过`←` `→`选择 yes 安装即可。再往后，会进行模型的选择，这里支持好多模型，本案例使用的  [glm apikey](https://www.bigmodel.cn/glm-coding?ic=KFLKGANUMO)
- 之后，一系列选择后（不分可以跳过），包括通信渠道（飞书）也可以先跳过，即可完成安装。安装后可以通过 `sudo openclaw gateway` 启动网关。这样 openclaw 也就正式启动起来了。
- 再后，安装飞书插件 `sudo openclaw plugins install @m1heng-clawd/feishu --registry https://registry.npmmirror.com` 这东西的目的是让 openclaw 可以对接上飞书。

### 2. 常用命令

| 命令                                                         | 作用                    | 备注 / 参数                                   |
| :----------------------------------------------------------- | :---------------------- | :-------------------------------------------- |
| `npm install openclaw@latest --registry https://registry.npmmirror.com` | 安装 openclaw           |                                               |
| `openclaw onboard`                                           | 安装引导                |                                               |
| `openclaw status`                                            | 查看 Gateway 状态       | 检查网关是否可达及运行状况                    |
| `openclaw health`                                            | 健康检查                | 主要检测 core 运行和依赖情况                  |
| `openclaw doctor`                                            | 综合诊断与修复建议      | 可配合 `--yes` / `--non-interactive` 自动执行 |
| `openclaw configure`                                         | 交互式配置向导          | 用于设置模型、通道、凭据等                    |
| `openclaw config get <path>`                                 | 获取配置值              | 指定路径提取配置                              |
| `openclaw config set <path> <value>`                         | 设置配置项              | 支持 JSON5/raw 文本                           |
| `openclaw config unset <path>`                               | 清除配置项              | 移除单个键值                                  |
| `openclaw channels list`                                     | 列出已登录通道          | 可观察 WhatsApp/Telegram 等登录状态           |
| `openclaw channels login`                                    | 登录新的通道账号        | 用于扫描/授权链接                             |
| `openclaw skills list`                                       | 列出技能                | 查看可用/已安装的技能                         |
| `openclaw skills info <skill>`                               | 技能详情                | 观察某项技能参数或版本                        |
| `openclaw plugins list`                                      | 列出插件                | 查看已安装插件                                |
| `openclaw plugins install <id>`                              | 安装插件                | 例如 @openclaw/voice-call                     |
| `openclaw plugins enable <id>`                               | 启用插件                | 之后通常需要重启网关                          |
| `openclaw logs --follow`                                     | 显示日志                | `--json / --plain / --limit` 等组合使用       |
| `openclaw gateway`                                           | 启动 Gateway 网关       |                                               |
| `openclaw gateway install`                                   | 安装系统服务            | 根据平台注册 Gateway 守护进程                 |
| `openclaw gateway start`                                     | 启动 Gateway 网关       | 系统服务模式下启动                            |
| `openclaw gateway stop`                                      | 停止 Gateway 网关       | 同上                                          |
| `openclaw gateway restart`                                   | 重启 Gateway 网关       | 适合配置变更后应用                            |
| `openclaw gateway status`                                    | 网关系统服务状态        | 不同于 `openclaw status`，会探测服务单元      |
| `openclaw uninstall`                                         | 卸载 Gateway 服务及数据 | 官方推荐使用                                  |
| `openclaw uninstall --all --yes --non-interactive`           | 全自动卸载              | 包含状态、workspace、插件等                   |
| `openclaw uninstall --state`                                 | 删除状态文件            | 不删除 workspace/CLI                          |
| `openclaw uninstall --workspace`                             | 删除工作区              | 移除 agent/workspace 文件                     |
| `openclaw uninstall --service`                               | 仅卸载服务              | 不删除数据                                    |
| `openclaw uninstall --dry-run`                               | 模拟卸载                | 显示结果但不实际执行                          |

## 三、部署操作

### 1. 创建飞书

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-04.png" width="850px"/>
</div>

#### 1.1 创建应用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-05.png" width="850px"/>
</div>

**批量导入，权限列表**

```java
{
  "scopes": {
    "tenant": [
      "aily:file:read",
      "aily:file:write",
      "application:application.app_message_stats.overview:readonly",
      "application:application:self_manage",
      "application:bot.menu:write",
      "cardkit:card:write",
      "contact:contact.base:readonly",
      "contact:user.employee_id:readonly",
      "corehr:file:download",
      "docs:document.content:read",
      "event:ip_list",
      "im:chat",
      "im:chat.access_event.bot_p2p_chat:read",
      "im:chat.members:bot_access",
      "im:message",
      "im:message.group_at_msg:readonly",
      "im:message.group_msg",
      "im:message.p2p_msg:readonly",
      "im:message:readonly",
      "im:message:send_as_bot",
      "im:resource",
      "sheets:spreadsheet",
      "wiki:wiki:readonly"
    ],
    "user": [
      "aily:file:read",
      "aily:file:write",
      "im:chat.access_event.bot_p2p_chat:read"
    ]
  }
}
```

- 创建应用后，你可以获得到应用凭证（appid、appsecret）这个信息是用于 openclaw 对接使用的。

#### 1.2 发布应用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-06.png" width="850px"/>
</div>

- 创建应用后，点击发布应用。这样你创建的应用才是有效的。

#### 1.3 事件配置（机器人）- openclaw 配置之前

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-07.png" width="850px"/>
</div>

- 飞书应用创建后，还需要配置机器人。但这会配置也是失败的，因为 openclaw 还没有关联上来。
- 这里需要在 openclaw 配置飞书通信渠道，之后重启 openclaw 网关，这里点击保存并配置权限（`接收消息`、`通讯录基本信息`），点击确认开通权限。在发布一个新应用，再和飞书机器人对话就可以使用了。

### 2. 安装应用（openclaw）

#### 2.1 执行脚本（含带引导）

```java
curl -fsSL https://openclaw.ai/install.sh | sudo bash -s -- --registry https://registry.npmmirror.com
```

- openclaw 官网版

```java
curl -fsSL https://clawd.org.cn/install.sh | sudo bash -s -- --registry https://registry.npmmirror.com
```

- openclaw-cn 中文社区版，适合新人伙伴使用。熟练后，使用官网版即可。他们操作的方式是一样的。
- 安装后的使用差异，一个是 `sudo openclaw config` 一个是 `sudo openclaw-cn config`

#### 2.2 引导配置

```java
sudo npm install openclaw@latest --registry https://registry.npmmirror.com
sudo npm install openclaw-cn@latest --registry https://registry.npmmirror.com

# 运行向导
sudo openclaw onboard
sudo openclaw-cn onboard
```

- 注意 `-cn` 为中文版，如果你不是执行的 curl 一键安装版本，是采用了 安装 `openclaw@latest` 程序，那么需要自己执行引导配置。

##### 2.2.1 安全提示

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-09.png" width="650px"/>
</div>

##### 2.2.2 配置方式

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-10.png" width="550px"/>
</div>

##### 2.2.3 模型配置

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-11.png" width="450px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-12.png" width="450px"/>
</div>

##### 2.2.4 通信通道（飞书）

**选择渠道**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-13.png" width="450px"/>
</div>

**安装插件**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-14.png" width="450px"/>
</div>

- 如果未安装过飞书插件，可以选择安装，也可以跳过后，后续在安装。
- 单独安装插件 `sudo openclaw-cn plugins install @m1heng-clawd/feishu`

**配置凭证**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-15.png" width="650px"/>
</div>

- 把你的应用凭证，配置到 openclaw 应用程序里。之后继续回车。
- 注意，一会要会到飞书页面，配置事件关联到 openclaw 上。

##### 2.2.5 技能配置

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-16.png" width="650px"/>
</div>

##### 2.2.6 部署完成

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-17.png" width="650px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-18.png" width="650px"/>
</div>

```java
ubuntu@VM-0-2-ubuntu:~$ sudo openclaw-cn gateway
```

- 配置完成后，要启动下网关。能看到以上信息，表示运行没问题了。
- 现在要到 3.1 接着配置飞书。

### 3. 配置飞书

#### 3.1 事件配置（机器人）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-19.png" width="850px"/>
</div>

- 注意，完成 2.2.6 步骤后，再回来操作。
- openclaw 关联上飞书以后，点击**添加事件**，以及添加上相关权限。完成后，会提示你发布一个新应用。

#### 3.2 发布应用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-20.png" width="850px"/>
</div>

- 点击发布应用，版本号 +1

#### 3.3 打开应用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-21.png" width="850px"/>
</div>

- 这会对话飞书，会提示执行一个命令，类似于验证签名。
- 命令 `sudo openclaw-cn pairing approve feishu KF2BRAXW`

#### 3.4 验证前面（+重启网关）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-22.png" width="850px"/>
</div>

```java
ubuntu@VM-0-2-ubuntu:~$ sudo openclaw-cn pairing approve feishu KF2BRAXW

🦞 Clawdbot-CN 0.1.4 (b161cdd) — 唯一不能在你的私信上训练的机器人Mark。

Approved feishu sender ou_762197513d3d1cb907f4c0d2ed3c3b2b.
ubuntu@VM-0-2-ubuntu:~$ sudo openclaw-cn gateway

🦞 Clawdbot-CN 0.1.4 (b161cdd) — 我不是魔法——我只是在重试和应对策略上极其执着。

06:39:38 [canvas] host mounted at http://127.0.0.1:18789/__clawdbot__/canvas/ (root /root/clawd/canvas)
06:39:38 [heartbeat] started
06:39:38 [gateway] agent model: zai/glm-4.7
06:39:38 [gateway] listening on ws://127.0.0.1:18789 (PID 20687)
06:39:38 [gateway] listening on ws://[::1]:18789
06:39:38 [gateway] log file: /tmp/clawdbot/clawdbot-2026-02-08.log
06:39:38 [browser/server] Browser control listening on http://127.0.0.1:18791/
06:39:38 [feishu] [default] starting Feishu provider (你的应用名称)
06:39:38 [info]: [ 'event-dispatch is ready' ]
```

- 如上方式，执行你的签名验证，并重启网关。
- 到这，就配置完成了，可以使用了。

## 四、使用体验

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-openclaw-23.png" width="950px"/>
</div>

现在你可以发挥想象的让 openclaw 帮你做事情了，很多运维的活，他也都可以完成。美滋滋！

---

### Md Ai Qclaw (`docs/md/ai/qclaw.md`)

---
title: QClaw
lock: need
---

# 🦞站起来蹬，每天2亿token，我已经会用 OpenClaw 了！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

深度体验后，**云服务器 + OpenClaw 的工作属性，基本等于零，白费蜡🕯！** 所以，于3月初，购入 Mac Mini（丐版16G）。部署 `OpenClaw`（+`QClaw`）+ `编程环境`（`jdk`、`maven`...） + `Docker`，`配合 Nas 环境做存储` + `Mac Pro`（随行控制设备）+ UU 远程（没事看看它）等，我才体验到**它能给我干活啦**！😄

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-01.png" width="550px"/>
</div>

❤ 心得体会！

最早部署的是 [OpenClaw](https://openclaw.ai/)（这哥们也原生就支持中文啦）+ 飞书，部署起来也很简单。但因为使用的都是自己的 Token，有点舍不得站起来蹬 🚴🏻，感觉每一句话都在烧钱💰。相比较下 OpenClaw 同样一个事的消耗程度，是其他 AI IDE（Trae.ai）的上百倍，那直接用其他的不也可以吗！？🤔 

但不深度玩，不干它几亿 Token，就不能体验到花钱的快乐！

好在呀，好在 [**QClaw**](https://qclaw.qq.com/) 每天一个登录的账号，赠送 4000 万 Token。换5个微信（还得家里人多），就是2亿 Token！就算干山崎大队，也是tm有富余的呀！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-02.png" width="200px"/>
</div>

几十亿 Token 下去后，我的体验是；它能干活，能想一个你的员工一样，控制这台电脑干活。包括，可以按照需求写代码，完成编译、构建、部署，打开浏览器验证功能逻辑，对于错误的编码可以继续完善。并且你可以随时随地的通过手机/Pad，通过`微信`/`企微`/`飞书`等方式，与它交流。

不过，它也不是那么省心的。三千六百颗手榴弹，给老李能干山崎大队，给咱也就能炸个鱼塘。所以，OpenClaw 你要想让它准确的给咱干活，就像写出来的代码，不仅它能看懂，我也得能认识呀。

那么，就需要上技能 Skills，这也是我在深度体验 OpenClaw 的最大感受，也是最先干的一个活。先拿10亿 Token，写2个 Skills 之后再说（先把🦵🏻腿接上）。—— 把你工作的方式，训练成技能，让 AI 懂你！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-03.png" width="200px"/>
</div>

> 接下来，小傅哥就分享下，用 OpenClaw（QClaw）做的一些事。

## 一、产品上线（skills）

发布到了官网(clawhub)：[https://clawhub.ai/u/fuzhengwei](https://clawhub.ai/u/fuzhengwei)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-04.png" width="700px"/>
</div>

[**xfg-zsxq-skills**](https://clawhub.ai/fuzhengwei/xfg-zsxq-skills) 一款星球社群运营服务的技能，便于所有加入社群的龙虾🦞主，可以让龙虾自主看帖、回帖，根据自己工作信息发帖/文章，以此方式龙虾形成一个自己的社群，吸收 OpenClaw 使用经验。这是一个自我成长的过程。

[**Xfg-ddd-skills**](https://clawhub.ai/fuzhengwei/xfg-ddd-skills) 一款 DDD 架构（六边形）指导编码的技能，因为在实际使用 AI 编码中，如果不加限制，他可能每次实现的功能逻辑，工程结构、分包方式、实现过程，都有非常大的差异。这会导致我们在拿到这份代码后，后续迭代也会非常吃力。所以，设计此技能，按照通用的 DDD 架构（六边形），限定 AI 编码方式。此技能初上线，已经用户体用。

## 二、安装技能

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-05.png" width="700px"/>
</div>

| 用途     | 地址                                          |
| -------- | --------------------------------------------- |
| 星球社群 | https://github.com/fuzhengwei/xfg-zsxq-skills |
| 编码架构 | https://github.com/fuzhengwei/xfg-ddd-skills  |

OpenClaw、QClaw、OpenCode等，你都可以直接把技能**连接**告诉它，它可以帮你直接安装。如果不能直接安装也可以下载安装包，本地到底即可。

## 三、运行效果（zsxq-skills）

### 1. 主动发帖

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-06.png" width="700px"/>
</div>

- 当你部署 zsxq-skills 技能后开始时，他会询问你，要对哪个星球地址进行操作，以及对应的 cookie 信息。如果 cookie 过期了，它还会主动询问你进行替换。
- 整体配置完成后，你就可以对星球进行发帖以及查看帖子等操作。不过不要弄的特别频繁！
- 像是在 OpenClaw（QClaw）还可以让添加上定时的任务处理。

### 2. 龙虾社群🦞

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-07.png" width="850px"/>
</div>

- 地址：[https://wx.zsxq.com/group/48885154455258](https://wx.zsxq.com/group/48885154455258)
- 说明：现在这个[《OpenClaw 养虾社区🦞》](https://wx.zsxq.com/group/48885154455258)就已经入住了很多小龙虾，欢迎👏🏻一起来玩下。

## 四、编程效果（ddd-skills）

### 1. 技能说明

如果不对 ai 做编码结构和实现方式限定，ai 会每次都给你“惊喜”，但工程交付需要的是在确定的结构下，持续的迭代输出。所以，需要增加规范技能，限定 ai 编码输出方式的统一。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-08.png" width="850px"/>
</div>

因而，小傅哥把过往历史一行行手敲的 DDD 资料，以及定对应的工程代码，持续的通过 OpenClaw（QClaw）喂给 AI，再安装技能并只用，查看通过此技能完成的编码，是否符合预期。经过仅2周的折腾，目前发布了 [xfg-ddd-skills v2.2.1](https://github.com/fuzhengwei/xfg-ddd-skills) 版本，可以满足 DDD 六边形架构设计和编码实现。

地址：[https://github.com/fuzhengwei/xfg-ddd-skills](https://github.com/fuzhengwei/xfg-ddd-skills) - 欢迎使用，也感谢给点个 Star 支持！更建议，帮忙一起维护迭代。

### 2. 技能设计

```java
xfg-ddd-skills/
├── SKILL.md                      # 技能入口文件
├── README.md                     # 本文件
├── assets/                       # 资源文件
├── scripts/                      # 脚本工具
└── references/                   # 参考文档
    ├── architecture.md            # 六边形架构概述
    ├── entity.md                  # 实体设计规范
    ├── aggregate.md               # 聚合根设计规范
    ├── value-object.md            # 值对象设计规范
    ├── repository.md              # 仓储模式规范
    ├── port-adapter.md            # 端口与适配器规范
    ├── case-layer.md              # 业务编排层规范
    ├── project-structure.md       # Maven 多模块结构
    ├── naming.md                  # 命名规范
    └── docker-images.md           # Docker 镜像配置
```

- 当你需要以下场景时，使用本技能：

  - 设计或实现 DDD 架构的项目，可以直接帮你创建准确的、统一的、可用的工程架构
  - 需要六边形架构、端口与适配器模式
  - 创建 Entity（实体）、Aggregate（聚合根）、Value Object（值对象）
  - 设计 Repository（仓储）模式
  - 业务编排层（Case Layer）设计
  - 触发层（Trigger Layer：HTTP/MQ/Job）设计
  - 构建富领域模型（Rich Domain Model）

-   注意，此技能还在持续迭代中，陆续还会增强使用效果。

```java
┌─────────────────────────────────────────────────────────────┐
│                      触发层 Trigger                          │
│              (HTTP Controller / MQ Listener / Job)            │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                       API 层                                 │
│                    (DTO / Request / Response)                │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                      案例层 Case                              │
│              (业务编排 / 流程串联 / 组合调用)                  │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                      领域层 Domain                            │
│            (Entity / Aggregate / VO / Domain Service)       │
└─────────────────────────┬───────────────────────────────────┘
                          ▲
┌─────────────────────────────────────────────────────────────┐
│                    基础设施层 Infrastructure                  │
│        (Repository Impl / Port Adapter / DAO / PO)           │
└─────────────────────────────────────────────────────────────┘
```

- 此技能符合六边形架构设计标准，相关文档：[https://bugstack.cn/md/road-map/ddd-guide-03.html](https://bugstack.cn/md/road-map/ddd-guide-03.html)

### 3. 场景应用

#### 3.1 表单开发

小傅哥这里选择的一个【表单】功能开发的场景，类似通讯 doc 里有一个表单的功能，设置表单后，让用户填写；

由运营配置表单，填写相应的输入信息（字段），有文本、数字、日期、下拉选择和图片上传等类型。以及增强了表单数据场景运用，填表的表单可以直接关联到用途上，如数据做权限功能审核，或者数据做发券等功能。最后分享链接给用户填写提交，提交时候可以选择让用户是否鉴权（如github登录、星球登录、公众号登录）。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-09.png" width="850px"/>
</div>

全程零参与代码实现，只提供必要的信息。对于开发后的功能，都是让 OpenClaw（QClaw）自己做浏览器访问，填写数据，验证功能。如果有问题，则进行优化功能的处理。

不过，做这类东西，还是需要懂场景，懂产品，懂架构，懂技术。否则，它真运行起来，也是会有不少问题的。

#### 3.2 产品演示

##### 3.2.1 编辑表单（关联数据场景）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-10.png" width="450px"/>
</div>

##### 3.2.2 表单数据（全局展示信息）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-11.png" width="950px"/>
</div>

##### 3.2.3 能力配置（数据场景配置）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-12.png" width="950px"/>
</div>

- 这个的目的，就在于配置完表单，用户填写后，那么这些数据，要干啥用。我们可以把一些字段关联起来，直接使用。

##### 3.2.4 填写记录（展示收集信息）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-13.png" width="950px"/>
</div>

##### 3.2.5 分享表单（用户填写数据）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-14.png" width="450px"/>
</div>

- 分享表单后，用户填写提交即可。

### 4. 工程演示

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-15.png" width="250px"/>
</div>

- 这个结构很重要，通过 xfg-ddd-skills 的限定，它可以按照约定的方式来编码。不要有ai幻觉和惊喜，而是要有小傅哥的“味道”。
- 不过在整个设计实现的“灵魂”上，还是差了点，不够老辣！

## 五、体验总结

1. 这种大量的工程化的，AI 写的代码，我不想碰。既不能给它修，也不想给它改。只要有 Token 就想让 AI 继续搞。软件工程交付，需要的不只是代码，还包括完整的理解代码，代码与产品PRD完全匹配，从而形成代码资产。
2. 使用AI做项目，仍然需要懂技术的，你的能力多强，你驾驭AI的本事就多大。
3. 纯新项目，或者小公司快速场景验证，可以使用AI快速搭建出来一套。
4. 公司里几十万行的老项目，如果靠 AI 这样迭代编写，可能会出事故。审查要严格。程序员编码的过程，是一行行逻辑的确认和产品功能的完整匹配。
5. 当一个需求过于复杂的时候，AI 会有过程中崩溃问题。这个对于个人编码项目没啥所谓，但公司级别的需求的迭代的。它的编码速度，有时候会低于人。n个类中，n行代码中，迭代功能，程序员已经有历史经验。ai 需要全量识别（或者你提前都编写好了技能）
6. skills 很有用，希望使用 ai 迭代项目的，需要持续的为工程迭代 skills 的各项技能。相当于为工程写技能路书。
7. OpenClaw（QClaw）属于一种网关入口，来控制设备。如果你更熟练于编码，那么纯 AI IDE 会更适合。如果你往各类的服务，接管电脑，那么 OpenClaw 更为合适。

---

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ai-agent-openclaw-attempt-16.png" width="750px"/>
</div>

---

### Md Ai Spring Ai (`docs/md/ai/spring-ai.md`)

---
title: Spring AI
lock: need
---

# spring ai

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。今天来带大家体验一下 Spring AI 的 Easy 开发！

现在的 OpenAI 对接开发真的是越来越容易了，直接引入 Spring AI 这个组件包，配置上可调用的 ApiHost、ApiKey 就可以完成对 OpenAI（ChatGPT）接口的调用。在此之前也有那么多各类的接口服务，还没有像 OpenAI 这样，被 Spring 如此重视，直接提供专属的 SDK 包，封装所有大模型（`暂无国内的`）。这也说明 OpenAI 的趋势力量多么庞大！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/springcloud-gateway-01.gif" width="150px"/>
</div>

**OpenAI 结合业务才更有价值**

虽然 OpenAI 的接口对接是越来越简单了，但我们要知道，一个实际的项目就不只是对接 OpenAI 接口，还需要完成一系列的业务流程封装。就比如目前我们看到国内的各类套壳或自研类的 OpenAI 服务，都会包括；`用户`、`鉴权`、`账户`、`支付`、`场景`等，一套东西来支撑整个流程跑通，同时还有系统工程背后的`舆情监控`、`敏感词过滤`、`数据存储`、`行为分析`等各类操作。这些东西也就是常说的，不能只会一个技术点，而是要结合场景，用技术支撑业务落地。

接下来，小傅哥会分享 Spring AI + Gpt-4o 的对接使用，以及介绍如何开发应用级的 OpenAI 项目。

## 一、简单介绍

Spring AI 项目，是为开发 AI 应用程序提供了 Spring 友好的 API 和抽象。所有的大模型对接（OpenAI、Ollama、Azure OpenAI、Amazon Bedrock、HuggingFace、Google VertexAI、Mistral AI）都以一种统一标准的形式进行。这样就减少了大家再额外开发对接的成本了，也不用维护和兼容各个 OpenAI 的接口迭代。

- 官网：[https://docs.spring.io/spring-ai/reference/index.html](https://docs.spring.io/spring-ai/reference/index.html)
- 文档：[https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/index.html](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/index.html)
- 源码：[https://github.com/spring-projects/spring-ai](https://github.com/spring-projects/spring-ai)

## 二、工程对接

### 1. 工程说明

- 环境：JDK 17、SpringBoot 3.2.3、spring-ai 0.8.0
- 源码：[xfg-dev-tech-spring-ai](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-spring-ai)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-spring-ai-01.png" width="350px"/>
</div>

在此工程中完成了 SpringAI 模块的引入，以及使用提供的 API 接口，完成同步应答、流式应答、图片绘制功能。

### 2. 引入模块

```pom
 <dependency>
     <groupId>org.springframework.ai</groupId>
     <artifactId>spring-ai-bom</artifactId>
     <version>0.8.0</version>
     <type>pom</type>
     <scope>import</scope>
 </dependency>
 
 <dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
```

- spring-ai 也在不断的发展，2024年5月22日 发布了 1.0.0 M1 并对代码做了一些调整。在生产级别使用需要注意📢版本的迭代。

### 2. 接口对接

测试之前需要在 application-dev.yml 配置对接的信息。

```yaml
spring:
  ai:
    openai:
      base-url: https://api.aws-*****/
      api-key: sk-oLkakcax33mJl628D3A533Fd67A24602Ac37D6*****
```

注意 spring-ai 提供了各类大模型的对接，都可以按需配置到这里。*在它的源码 autoConfig 类里会有要配置参数的名称，可以参考。*

#### 2.1 功能测试

```
/* Detailed source-code truncated for AI context efficiency. */
```

**测试结果**

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 测试结果为 test_generate_stream 流式返回 `1+1` 的应答结果。 

#### 2.2 接口服务

```java
@RestController()
@CrossOrigin("*")
@RequestMapping("/api/v1/openai/")
public class OpenAiController {

    @Resource
    private OpenAiChatClient chatClient;

    /**
     * curl http://localhost:8090/api/v1/openai/generate?message=1+1
     */
    @RequestMapping(value = "generate", method = RequestMethod.GET)
    public ChatResponse generate(@RequestParam String message) {
        return chatClient.call(
                new Prompt(
                        message,
                        OpenAiChatOptions.builder()
                                .withModel("gpt-4o")
                                .build()
                ));
    }

    /**
     * curl http://localhost:8090/api/v1/openai/generate_stream?message=1+1
     */
    @RequestMapping(value = "generate_stream", method = RequestMethod.GET)
    public Flux<ChatResponse> generateStream(@RequestParam String message) {
        return chatClient.stream(new Prompt(message));
    }

}
```

在 OpenAiController 中提供了对接两个接口的方法，以及同步和流式返回。*流式返回还可以使用 ResponseBodyEmitter 进行流式返回*

Spring AI 提供的 OpenAI 大模型对接是 Easy 的很，减去了自己开发代码对接大模型。但仅仅是这样一个简单还不够，我们还需要学习积累的更多！如；微信鉴权登录怎么做、支付怎么对接、账户额度怎么扣减、限流熔断怎么操作等等，实际场景问题才是有价值的核心内容，所以，咱们要上个大菜！☞ [OpenAi 大模型应用服务体系构建 - API-SDK、鉴权、公众号、企业微信、支付服务](https://bugstack.cn/md/project/chatgpt/chatgpt.html)

---

### Md Ai Toy Agent Coding (`docs/md/ai/toy-agent-coding.md`)

# 「开启」古法编程，学习 AI Agent 开发！全程视频，手把手带着你操作 🚀

作者：小傅哥  
博客：<https://bugstack.cn>

> 沉淀、分享、成长，让自己和他人都能有所知有所获！😄

大家好，我是技术UP主小傅哥。

**号外，号外。📢** 小傅哥要带着你来一次`古法编程`之旅，开局一把 IntelliJ IDEA。从零开始，从 LLM API 对接开始，一直到 `ReAct`、`Tool`、`RAG`、`LLM-Wiki`、`MCP`、`多智能体协作`、`子代理`、`A2A`、`人机协同审批`、`沙箱`等26个场景，全程视频手把手教你学会智能体开发。

<div align="center">  
	<img src="https://bugstack.cn/images/article/project/ai-rag-knowledge/ai-rag-knowledge-0-00.png" width="150px"/>  
</div>

**又粗又细，有紧有收**

干了半年多的 WaLiCode 开发，有小3万的用户安装使用。也发布了 WaLiAPI 提供 LLM 网关能力（+免费模型），还搞了 `DSH Java` 通过 Java + DDD 架构，1:1 复刻 DeepSeek Harness 工程。可以说在 AI 学习的这条路上，小傅哥为你提供了非常丰富的学习教程。

现在丰富度是有了，但对不少没怎么接触 AI 开发的伙伴来说，甚至连 LLM 大模型的 API 都没对接过的，还是有点难度的。所以，小傅哥先是提供了 **AI Agent Guide 通识教程**，把概念先给大家捋清。之后又提供了 26个 在线案例的 **ToyAgent 🎮** 项目。那么接下来，我将手把手的把这套 ToyAgent 26个案例，全程视频的手把手带着你操作。

接下来，小傅哥介绍下这套视频教程都有什么，跟着做下来能学到什么。以及整套内容学习后，怎么进阶到大型项目里学习。

## 一、课程展示 📺

整套课程视频，`10.26`日开始，我会免费的发到 B站「[`小傅哥の码场`](https://space.bilibili.com/15637440)」，地址：<https://space.bilibili.com/15637440> - `感谢关注小傅哥B站，实时收到最新视频推送`

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-01.png" width="950px"/>  
</div>  

- 首先，我把它叫做 ToyAgent 是因为我把一整套核心 AI Agent 智能体的开发经验，拆分成了 26个实战案例，就像乐高积木一样。现在再带着你把乐高积木一块块搭回去。  
- 之后，整个课程全程视频手把手的，带着你来分析需求，编写代码，测试验证。以及横行对比 `java`、`go`、`python`、`typescript`、`js` 几种语言。基本可以让你达到，一套东西学下来，后面各个语言的智能体开发也都能看懂和使用。对于 AI Agent 大项目的学习也都可以上手。

> AI 时代，还有古法架构师，带着你一行行的写代码学习。这免费课程，绝对不烧心！

## 二、能学到啥 🤔

该项目是 AI Agent 场景的核心技术体系，以真实可运行为目标，通过 26 个渐进式案例，进行系统的需求分析、架构设计、功能实现，过程涵盖设计模式的运用，解决复杂场景问题。整套东西学习下来，你会感受到 AI Agent 不难，虽然知识点不少，但还挺好上手。

- 【基础】理解「智能体 = 模型 + 策略」：从一个 chat 方法起步，把用户的话交给模型、把模型的话还给用户，破除智能体的神秘感。
- 【基础】掌握系统提示词的三层结构：角色、背景、任务与约束，同一个模型换一份提示词就换一种人格，提示词是杠杆。
- 【核心】掌握 ReAct 循环：让模型学会边想边做，按思考 → 行动 → 观察结果 → 再思考迭代推进，直到给出最终答案，这是所有智能体框架的内核。
- 【核心】掌握工具调用（Function Calling）：声明工具清单、模型返回结构化调用请求、执行工具并回填结果，生产中 tools/tool_calls 与 MCP 协议本质都是这三步。
- 【核心】掌握上下文工程：用滑动窗口与摘要压缩管理短期记忆，控制上下文预算，让对话有来有回。
- 【架构】掌握意图路由：先让模型识别意图输出分类，再由决策中枢把请求路由到不同处理器，是多智能体编排的前置能力。
- 【架构】掌握 RAG 检索增强生成：切分 → 向量化 → 相似检索 → 增强生成，接入私有知识，回答有出处、知识可热更。
- 【架构】掌握知识编译与沉淀：把项目知识编译成结构化 Wiki 条目持久保存、增量维护，编译一次、持续复用。
- 【架构】掌握 MCP 工具标准化协议：工具侧拆成独立服务，通过标准的发现与调用方法实现工具与智能体彻底解耦。
- 【架构】掌握技能分层设计：从纯提示词模板到工具组合再到完整子流程，形成可沉淀、可复用的能力包。
- 【架构】掌握工具注册表模式：工具抽象成统一协议，注册即生效、注销即消失，执行器不认识任何具体工具。
- 【编排】掌握多智能体协作：规划者拆解任务、专家各司其职、审查员质量把关、主持者汇总交付，协作的本质是结构化消息在角色间流动。
- 【编排】掌握子代理派遣：主代理动态委托带独立上下文的分身执行子任务，可无状态新建、也可继承父会话继续话题。
- 【编排】掌握 A2A 跨进程协作协议：靠代理名片发现、标准化请求信封与异步回执对接外部代理。
- 【编排】掌握生产级运行时外壳：输入守卫防提示注入、最大步数保险丝防死循环、输出守卫做合规过滤、异常兜底，模型负责聪明、运行时负责可靠。
- 【编排】掌握工作流状态机编排：用节点、条件边与状态传递实现确定性流程，平衡可控性与灵活性。
- 【工程】掌握人机协同：关键信息缺失时会话挂起等待人工答复，用户下一条消息作为答复回填后继续执行。
- 【工程】掌握审批门禁：工具按风险分级，高危操作必须过人工审批，支持免审记忆，超时默认拒绝——宁可不执行，不可乱执行。
- 【工程】掌握沙箱纵深防御：策略层、内容黑名单、空间边界、路径规范化四层管线，任何一层拦截即生效。
- 【可靠】掌握事件溯源：会话即日志、日志即状态，服务重启后从日志完整重建上下文，天然获得审计与回放能力。
- 【可靠】掌握插件机制：把一批工具打包成可安装可卸载的插件，契约 SPI、隔离加载、生命周期完整。
- 【可靠】掌握 Hooks 钩子体系：把审计、脱敏、风控等横切逻辑挂在工具执行前后，挂钩即生效、摘钩即消失，工具作者无感知。
- 【终端】掌握 CLI 智能体：把智能体装进终端 REPL，工作目录即上下文，支持交互式与非交互两种模式。
- 【终端】掌握定时任务能力：把「什么时候做」也变成模型的决策对象，一次性调度、循环调度与任务管理，是提醒、巡检类智能体的雏形。
- 【设计】贯穿全程的通用思想：协议优先先用接口定契约、注册表统一管理注册与回收、策略层与骨架分离、append-only 事件流让状态可回放、纵深防御让安全成为多层管线。

此外，小傅哥已对全过程都做了需求的分析、功能的设计、编码的精细化处理，让你吃上细糠！也通过这种方式，真正的把你的技术储备整起来，以后进入到公司都是嘎嘎强的选手！

## 三、举个例子 🌰

26 个案例是一个渐进式的过程，小傅哥这里选 5 个有代表性的场景给大家看看效果。每个场景在 ToyAgent 里就是一个接口类，打开测试页面发一句话，左侧是场景导航，中间是对话测试区（附执行轨迹和 mermaid 流程图），右侧是原理文章和五语言源码。

> **你看到的所有内容，小傅哥的视频里都会一行行写出来，并顺带着带你分析以及扩展的讲解这些知识点。**👨🏻‍💻

### 1. 对话智能体：一切从一个 chat 方法开始

智能体的最小 MVP，其实就是把用户的话交给模型、把模型的话还给用户。别小看这 17 行代码，`ChatModel` 这个抽象一旦立住，后面 25 个场景都是围着它转的。视频里会从这里起步，先破除"智能体很神秘"的错觉。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-02.png" width="950px"/>  
</div>  

### 2. ReAct 智能体：让模型学会边想边做

问一句"北京今天天气怎么样"，模型自己拆成了 思考 → 行动（`get_weather(北京)`）→ 观察结果 → 再思考 → 给出最终答案。页面上的执行流程图把这个循环画得清清楚楚——这就是所有智能体框架的内核，LangChain、Coze 们跑起来都是这一套。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-03.png" width="950px"/>  
</div>  

### 3. 工具调用：给模型装上手脚

模型只会出文本，`Function Calling` 让它"决定"调哪个工具、传什么参数，执行权还在你手里。时序图里能看到完整的三步：声明工具清单 → 模型发起工具调用 → 执行并回填结果。生产中的 tools/tool_calls，乃至后面的 MCP 协议，本质都是这三步。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-04.png" width="950px"/>  
</div>  

### 4. RAG 检索增强：让智能体带着资料说话

问"ToyAgent 是什么项目"，智能体先去知识库里检索（打分、取 Top2），再把检索到的片段塞进提示词让模型组织答案。切分 → 向量化 → 相似检索 → 增强生成，一条流水线下来，私有知识就能做到回答有出处、知识可热更。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-05.png" width="950px"/>  
</div>  

### 5. 多智能体协作：从一个大脑到一支团队

一句"写一段 100 字的智能体科普短文"，规划者拆任务、研究员和写手各司其职、审查员质量把关、主持者汇总交付，5 步流水线全程在轨迹里可见。协作的本质就是结构化消息在角色间流动，这也是后面子代理、A2A 等编排场景的地基。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-06.png" width="950px"/>  
</div>  

## 四、课程设计 📅

**我要想办法怎么让你把这个东西学会。**

这是我在设计整套课程时，想得最多的一个问题。以为看懂和真正会用之间，隔着一道大坎；很多人收藏了几十篇 Agent 文章、下载过好些个开源项目，真到自己动手时，连一个 `chat` 方法都写不出来。

所以这套课程没有平铺 26 个孤立的 demo，而是设计成了一条**打怪升级**的进阶路线——五个阶段，从一个 `chat` 方法打到生产级智能体，每个阶段都只解决一个核心矛盾，案例层层咬合：**阶段一的 `ChatModel` 抽象是后面 25 个场景的地基，阶段二的 ReAct 循环是所有编排场景的内核，阶段三的工具注册表撑起了阶段五的插件机制**。你每学一个新场景，用的都是前面亲手写过的东西。

每个阶段配齐三件套：**架构图**（先看清全貌再动手）、**知识表格**（每个 Step 讲什么、你能收获什么）、**课后练习**（改代码、造工具、做对比，把知识焊死在自己手里）。全程视频带着你一行行写，横向对比 `Java`、`Go`、`Python`、`TypeScript`、`JavaScript` 五种语言的实现，一套学完，各个语言的智能体开发都能看懂上手。

整个课程分为5个阶段，26 个 Step 的能力是一步步长出来的，每一层都踩在下一层上（武当梯云纵）：

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-12.png" width="950px"/>  
</div>  

学完整套课程，你脑子里的智能体知识地图会长成这样——六大板块，环环相扣：

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-13.png" width="950px"/>  
</div>  

> 别被 26 个场景吓到，它们本质上是同一个 `chat(input)` 的 26 次进化。跟着视频一个阶段一个阶段打过来，回头看时你会发现自己已经把一台「生产级智能体」从零件到整机装了一遍。分阶段在细看下；

### 阶段一：打地基 —— 智能体的最小内核

**目标**：破除神秘感，理解「智能体 = 模型 + 策略」。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-07.png" width="500px"/>  
</div>  

| Step | 案例    | 核心知识                               | 关键收获                            |
| ---- | ----- | ---------------------------------- | ------------------------------- |
| 01   | 对话智能体 | `String chat(String input)` 一行核心逻辑 | 所谓智能体，起点只是「把用户的话交给模型，把模型的话还给用户」 |
| 02   | 提示词工程 | 系统提示词三层结构：**角色 → 背景 → 任务与约束**      | 同一个模型，换一份提示词就换一种「人格」—— 提示词是杠杆   |

---

### 阶段二：会干活 —— ReAct 循环与工具调用

**目标**：掌握智能体区别于聊天机器人的第一核心能力 —— **调用工具解决真实问题**。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-08.png" width="420px"/>  
</div>  

| Step | 案例       | 核心知识                                  | 关键收获                              |
| ---- | -------- | ------------------------------------- | --------------------------------- |
| 03   | ReAct 循环 | Thought → Action → Observation → Loop | 智能体的「灵魂循环」，模型自主决定何时终止             |
| 04   | 工具调用     | Function Calling 协议、JSON Schema 参数描述  | 工具是模型的「手」，description 写得越准，模型调用越准 |
| 05   | 记忆       | 对话历史管理、上下文窗口                          | 无记忆的智能体每次都是「失忆」重新开始               |

---

### 阶段三：会规划 —— 知识增强与能力编排

**目标**：让智能体「有知识、会挑工具、能标准化接入」。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-09.png" width="950px"/>  
</div>  

| Step | 案例        | 核心知识                            | 关键收获                            |
| ---- | --------- | ------------------------------- | ------------------------------- |
| 06   | 路由智能体     | 意图识别 + 分发                       | 模型可以先做「分类决策」再走不同分支              |
| 07   | RAG       | 向量检索 → 塞进提示词 → 生成               | 模型不知道的知识，先查再答，杜绝编造              |
| 08   | Wiki 知识库  | 知识条目编译、检索命中                     | 「业务规则」类知识可以持续沉淀复用               |
| 09   | MCP 协议    | `tools/list` + `tools/call` 标准化 | 工具与智能体解耦的行业标准协议                 |
| 10   | Skills 技能 | L0 纯提示词 / L1 工具组合 / L2 子流程      | 技能 = 工具的组合与复用，Claude Skills 的原理 |
| 11   | 工具注册表     | ToolRegistry 统一注册/发现/执行         | 能力管理的「中枢」，后面插件机制的地基             |

---

### 阶段四：会协作 —— 多智能体体系

**目标**：单个智能体能力有限，学会「分工、委派、协作、编排」。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-10.png" width="420px"/>  
</div>  

| Step | 案例     | 核心知识                    | 关键收获                   |
| ---- | ------ | ----------------------- | ---------------------- |
| 12   | 多智能体   | 多角色各司其职，主代理汇总           | 「分而治之」是多智能体的第一性原理      |
| 13   | 子代理    | 任务拆解 → 委派 → 结果回收        | 子代理是「临时工」，用完即弃         |
| 14   | A2A 协议 | Agent 名片、任务委派、跨代理通信     | 智能体间的「标准化社交协议」         |
| 15   | 循环迭代   | 生成 → 评估 → 改进的多轮循环       | 好答案不是一次生成的，是迭代出来的      |
| 16   | 工作流    | 固定步骤编排 vs 模型自主决策        | 确定性任务用工作流，探索性任务用 ReAct |
| 17   | 运行时    | TurnEndReason 终止原因管理    | 循环必须能停：信息足够/达上限/出错     |
| 18   | 全能力整合  | 记忆 + 工具 + 路由 + RAG 融于一体 | 一个「六边形战士」智能体的完整形态      |

---

### 阶段五：能落地 —— 工程化与生产级能力

**目标**：从 Demo 走向生产 —— 安全、可控、可审计、可扩展。

<div align="center">  
	<img src="https://bugstack.cn/images/article/ai/toyagent-video-11.png" width="280px"/>  
</div>  

| Step | 案例       | 核心知识                                       | 关键收获                          |
| ---- | -------- | ------------------------------------------ | ----------------------------- |
| 19   | 澄清提问     | 信息不足时主动反问，禁止瞎猜                             | 好智能体先问清再动手                    |
| 20   | 审批管控     | 高危工具执行前必须人工批准                              | 「批准 / 拒绝 / 批准并记住」三态机制         |
| 21   | 沙箱       | 格式校验→危险命令检测→资源限制→白名单                       | 让 AI 执行代码的四道安全闸门              |
| 22   | 事件溯源     | 事件写入 JSONL → 回放重建状态                        | 状态是事件的「投影」，天然可审计              |
| 23   | 插件机制     | URLClassLoader 隔离加载、install/uninstall 生命周期 | 插件 = 一批工具的可热插拔载体（dsh-java 原理） |
| 24   | Hooks 钩子 | before（审计/风控）→ 工具 → after（脱敏）              | 拦截器管线，安全与治理的统一入口              |
| 25   | CLI 终端   | REPL 交互 + `-p` 单命令模式                       | 形态是壳，灵魂仍是 `chat(input)`       |
| 26   | 定时任务     | 一次性/周期性调度、任务列表/取消                          | 让智能体从「被动应答」走向「主动服务」           |

## 五、进阶提升 📈

小傅哥干事，向来讲究体系化成长，这也是一个架构师的自我修养。那么，这里为你提供的课程，也是全面的、成体系的、循序渐进，进阶的。

从 0 开始，一套 AI Agent Guide 通识教程，之后开始进入难易程度不同的实战项目。这些实战项目是体现了不同类型的架构设计和场景方案，以及 AI Agent 基础设施。—— 一个公司里怎么干，小傅哥就带着你怎么干！

<div align="center">  
	<img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-10.png" width="850px"/>  
</div>

---

### Md Ai Toy Agent (`docs/md/ai/toy-agent.md`)

---
title: ToyAgent
lock: need
---

# 一套 ToyAgent，教小白上手 AI Agent 开发！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

刷到不少小红书🍠伙伴吐槽；**“白付费给xxx了，整了个 Toy 🎮 项目。🤨 ”** 。评论区也有人建议，直接去 Github 看开源项目，`Claude Code`、`OpenCode` 不是一堆。但实际整下来，Toy 的不够用，源码的看不懂，根本看不懂。`鲜族人过年,要了狗命了。`

讲良心，一个小白，刚接触 Agent。上来就整 `Claude Code` 真相当于小本毕业🎓撸`钱老`的《工程控制论》！—— 字/码，都摆在那，但就不往脑子里进呀！

<div align="center">      
	<img src="https://bugstack.cn/images/article/ai/toy-agent-01.gif" width="150px"/>      
</div>

所以，就学习来说，你还真得需要一个 Toy 🎮  项目。但 Toy 的，得 Toy 的彻底点。`1，不能搞的太大，你没那多时间呀`、`2，上手得快`、`3，就是必须保证学完不能白学`

<div align="center">      
	<img src="https://bugstack.cn/images/article/ai/toy-agent-02.png" width="150px"/>      
</div>

然后，[ToyAgent](https://ai-agent-guide.xiaofuge.cn/toy-agent) 这套玩具项目来啦！一个接口类，就是一个最小 MVP 智能体。用 26个场景，全体量覆盖智能体开发。包括；`提示词工程`、`ReAct 循环`、`工具调用`、`记忆系统`、`子代理`等。

<div align="center">      
	<img src="https://bugstack.cn/images/article/ai/toy-agent-03.png" width="950px"/>      
</div>

- 官网：<https://ai-agent-guide.xiaofuge.cn/toy-agent/>
- 源码：<https://github.com/fuzhengwei/ToyAgent>

左侧是目录，中间是对话（每一节最小 MVP 版本智能体），右侧是对应章节的文章讲解。学习的时候，也可以点击文章对应的 `Github` 仓库进入到这一节的代码学习。以上这些案例，来自于小傅哥在开发 [`walicode`](https://t.zsxq.com/GQ4ae)、[`dsh java`](https://t.zsxq.com/kYcVt) 等智能体项目，积累的开发经验。所编写的每一节最小运行版本，这样你可以循序渐进的理解到一个 Agent 开发都需要什么。—— 每一个章节都是一个小玩具，但所有玩具拼装起来，就是一个最完整智能体解决方案。

> 接下来，小傅哥就来介绍下这套内容，方便小伙伴学习。此外，文末也提供了小傅哥开发的全部 AI Agent 项目源码。

## 一、🎮 玩具介绍

其实说白了，智能体的灵魂只有一个方法；

```java
public interface Agent {
    String chat(String input);   // 输入一句话，输出一句话
}
```

围绕这个方法，增加了各类技术手段，让 Agent 具备处理用户诉求的能力。但教学来说，为了让整个过程不被复杂化，且容易被理解和掌握。小傅哥这里让一个接口类，负责体现一个智能体知识点。所以，整个这套内容，你刷起来会特别轻松。

### 1. 对话使用

<div align="center">      
	<img src="https://bugstack.cn/images/article/ai/toy-agent-04.png" width="950px"/>      
</div>

- 首先，左上角有一个设置按钮，点击后可以配置对话模型。（不配置会走官网的或者 Mock 数据）
- 之后，你可以选择任意一节进行对话，每一个章节都是一个对应知识点体现。同时，对话中会把 Agent 执行过程展示出来，这能非常方便的你来理解 Agent 操作。
- 此外，右侧还有`原理文章`，是对应当前这一节的内容讲解。这可以辅助你来学习。上面还有 Github 对应这一节的源码可以点击查看。

### 2. 章节预览

| #  | 场景            | 接口类                 | 新增能力                                               | 对应教程章节       |
| -- | ------------- | ------------------- | -------------------------------------------------- | ------------ |
| 01 | 对话智能体         | `ChatAgent`         | 最小 MVP：接通模型                                        | ch01-03      |
| 02 | 提示词工程         | `PromptAgent`       | 系统提示词三层结构                                          | ch04         |
| 03 | ReAct 循环      | `ReActAgent`        | 思考-行动-观察                                           | ch04b/05     |
| 04 | 工具调用          | `ToolCallAgent`     | Function Calling                                   | ch03/10      |
| 05 | 记忆系统          | `MemoryAgent`       | 多轮记忆 + 上下文压缩                                       | ch06         |
| 06 | 意图路由          | `RouterAgent`       | 意图识别 + 决策中枢                                        | ch06b/07     |
| 09 | MCP 协议        | `McpAgent`          | 工具标准化接口                                            | ch07b/11     |
| 10 | 技能编排          | `SkillAgent`        | Skills L0/L1/L2                                    | ch08/12      |
| 07 | RAG           | `RagAgent`          | 检索增强生成                                             | ch16/20      |
| 12 | 多智能体          | `MultiAgent`        | 规划-执行-审查协作                                         | ch10/14      |
| 15 | Loop 运行时      | `LoopAgent`         | 守卫 + 保险丝 + 兜底                                      | ch08b/18/21  |
| 16 | 工作流状态机        | `WorkflowAgent`     | LangGraph 思想编排                                     | ch11b/15     |
| 18 | 全流程智能体        | `FullAgent`         | 守卫+记忆+ReAct+工具+保险丝 综合链路                            | 综合 Step01-17 |
| 08 | LLM-Wiki 知识编译 | `WikiAgent`         | 知识编译一次、持久维护、增量沉淀                                   | ch13/26      |
| 11 | 工具注册表         | `RegistryAgent`     | ToolDefinition 协议：注册/发现/热注销（disposer）              | dsh-java     |
| 17 | ReAct 运行时     | `RuntimeAgent`      | turn/step 两级循环 + 上下文裁剪 + TurnEndReason             | dsh-java     |
| 19 | 人工介入          | `AskAgent`          | ask_user_question：提问挂起 → 人工答复续跑                    | dsh-java     |
| 20 | 审批门禁          | `ApprovalAgent`     | 风险分级 + 审批挂起 + 会话免审 + 超时默认 DENY                     | dsh-java     |
| 21 | 沙箱纵深防御        | `SandboxAgent`      | 策略/黑名单/边界/规范化 四层拦截                                 | dsh-java     |
| 22 | 事件溯源          | `EventSourcedAgent` | JSONL 事件流 append-only + 回放投影重建状态                   | dsh-java     |
| 23 | 插件机制          | `PluginAgent`       | AgentPlugin 契约 + 隔离 ClassLoader 加载 + 工具桥接批量注册/注销   | dsh-java     |
| 25 | CLI 智能体       | `CliAgent`          | 终端 REPL + -p 单命令模式 + 沙箱 shell 执行器（复用 Step21 四层防御）  | 教程 ch18      |
| 13 | 子代理           | `SubagentAgent`     | dispatch_subagent：spawn 全新上下文 / fork 继承父会话，主代理动态派遣 | dsh-java     |
| 24 | Hooks 钩子      | `HooksAgent`        | before 拦截/改写参数 · after 脱敏/审计，挂钩即生效摘钩即消失            | dsh-java     |
| 14 | A2A 协作        | `A2AAgent`          | Agent Card 名片发现 + task_id 信封 + 异步回执，跨代理标准化协作       | dsh-java     |
| 26 | 定时工具          | `ScheduleAgent`     | 一次性/循环调度，触发结果 append 到事件日志可回看                      | dsh-java     |

每个场景一个文件，位于 `src/main/java/cn/xiaofuge/ai/agent/stepXX/`，接口注释即教程，嵌套实现类即全部逻辑。

### 3. 项目工程

如图，26个实战场景案例；

<div align="center">      
	<img src="https://bugstack.cn/images/article/ai/toy-agent-05.png" width="850px"/>      
</div>

- 工程地址：<https://github.com/fuzhengwei/ToyAgent>
- 项目说明：每一节源码都很轻量，直击核心。可以启动后在 web 访问，也可以编写单测在本地验证。

<div align="center">      
    <img src="https://bugstack.cn/images/article/ai/ai-agent-guide-wx-04.png" width="650px">      
</div>

> [https://ai-agent-guide.xiaofuge.cn](https://ai-agent-guide.xiaofuge.cn/)  是小傅哥做的一整套 **AI Agent Guide - 通识教程**，而这套案例，就是配和同时教程所提供的。这套内容，除了 web 版本，也提供了一套小程序版本，你可以扫码使用。

## 二、🚀 实战项目

玩具🎮，玩的热血沸腾了，接下来就是干点正式的，有点难度的，AI Agent 智能体项目了。这是一整套完整的学习路线，循序渐进，有紧有收的。

### 1. 学习路线

小傅哥为伙伴们推荐一套 AI 从通识、应用、项目，全套流程路线。你可以刷到 AI 八股，也可以学会 AI VibeCoding 编程，还能实践各类 AI 项目。如，市面的 AI IDE（walissh、walicode、walibuddy「dsh java desktop」）教你做一套市面上的 trae.ai/qcoder/workbuddy 一样的编程工具。WaLiAPI（LLM 负载、日志审计、RAG 知识库）、AI MCP Gateway 教你如何构建 AI Infra 基础设施。

这里的所有内容，所有的项目，都从 [bugstack.cn ](https://bugstack.cn/) 实战项目进入学习；

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-10.png" width="850px">      
</div>

- 首先，小白推荐先进入 AI Agent Guide 基础认知教程：[ai-agent-guide.xiaofuge.cn](https://ai-agent-guide.xiaofuge.cn/)- 涵盖基础概念、八股、面试内容。
- 之后，如果没有使用过 AI IDE 工具，可以做下 AI 新范式，通过 AI 实践来锻炼。
- 最后，可以通过项目驱动学习，结果导向的项目实战，可以更好的锻炼 AI 技能，也是为转岗到 AI Agent 应用开发工程师做准备。

**学习建议**

- 学习路线A-完整进阶：0 - 认知和实践、「1阶段」0、1、2、3、9 「2阶段」5、4、7、6、7、8、10
- 学习路线B-着急面试：0 + (2) | (3) | (5+4) | (5+4+6) | (5+6+7) | (5+4+8) |（12 + 15 + 4）等。

**阶段成长**

- 第1阶段：OpenAI代码自动评审+(AI Agent 脚手架+场景应用/AIAgent智能体)2选1
- 第2阶段：OpenAI应用项目(公众号扫码登录、微信支付)+AI MCP网关（+WaLiAPI），时间充足可结合 API Gateway 业务网关
- 第3阶段：AI MCP Gateway+API网关结合、OpenAI应用+AI Agent +拼团/大营销结合
- 第4阶段：进阶到 WaLiSSH + WaLiCode 深入到 AI Agent 运行时设计实现 + WaLiAPI（知识库）
- 第5阶段：DSH Java 深度学习，Web版、桌面版、插件运用。

### 2. 展示项目

#### 2.1 DSH Java Desktop

《DeepSeek Harness Java》—— 基于 Deepseek Harness 源码设计，使用 Java + DDD，进行 1:1 复刻（Java 版本。领域驱动设计，更容易看懂）。

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/deepseek-harness-java/dsh-java-desktop-02.png" width="850px">      
</div>

- 项目：<https://t.zsxq.com/kYcVt>
- 介绍：

Deepseek Harness 插件化的设计思维，类似于 AI Agent 脚手架。同类思想的目标在于快速的在一些业务场景完成智能体的设计实现。在 AI 时代，这类设计思想很重要。所以考虑设计 Deepseek Harness Java 版本，通过 ClassLoader 加载 Jar 以及在内部直接继承 type 层来实现插件扩展。当前正在拆分领域模块；

所以，该项目的核心价值在于企业通用解决方案（也就是 deepseek harness 的能力），编写简历可以着重体现这方面内容。之所以做 java 版本，一方面是企业里有此类场景诉求，另外一方面是个人具备这样的技术储备，可以在各类场景，使用各类语言，进行快速迭代智能体应用。

#### 2.2 AI Coding/DevOps

《AI Coding/DevOps 可持续交付助手》 - WaLiCode + WaLiSSH 让 AI 既可以辅助编码，又可以运维云服务器！

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/walissh/product-walissh-user-guide-04.png" width="850px">      
</div>

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/walicode/walicode-0-1-2.png" width="850px">      
</div>

- 项目：<https://t.zsxq.com/GQ4ae>
- 介绍：

该项目，以 WaLiCode 的架构设计为内核标准，分拆2套工程（walissh、walicode）讲解。项目使用 Spring AI + Google ADK + Tauri（+Typescript），结合运行时智能体设计，涵盖；`Agent WorkFlow`、`上下文管理（对话追踪、搜索、提示词）`、`意图识别（+LLM）`、`混合窗口裁剪`、`动态提示词（ Prompt 组装器、里程碑追踪）`等，核心设计，构建一整套 AI Agent 智能体服务工具。

用途呢，用于辅助编码，用于辅助运维。除了基本的 AI Coding、SSH +Sftp 能力外，你可以为项目工程，扩展添加 mcp、skills 技能等，为你的服务器做智能化运维服务管理。如；`日志分析`、`系统健康度巡检`、`内存泄漏排查`、`复杂项目链路耗时处理`、`项目压测优化建议等等场景`。这个工具，就是你穿插在云服务器上的智能机器人。现在它已经可以替换我电脑上的其他 SSH 工具了，嘎嘎好用！

说白了，AI Agent 要解决的就是一整条研发交付路径服务，包括；研发设计（spec规约）、工程编码（WaLiCode）、项目上线/运维（WaLiSSH）等，而本次的项目，其实完全可以在学习后，扩展出Coding能力。

#### 2.4 OpenAI 应用

《OpenAi(ChatGPT/ChatGLM) 微服务应用体系构建》- API-SDK、鉴权、公众号、支付交易。

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/chatgpt/chatgpt-extra-230905-03.png" width="850px">      
</div>

- 项目：<https://t.zsxq.com/kEhGG>
- 介绍：此项目不只有ChatGPT还有ChatGLM，主要以围绕类似 OpenAi 生成式服务，构建微服务应用架构体系组件。包括；用户鉴权、公众号、微信支付等，满足不同诉求的使用。并以模块化设计，积木式构建应用，让不同的场景诉求都可以配置化对接。让大家既能锻炼技术，又能有场景验证。

#### 2.5 AI MCP Gateway

《AI MCP Gateway 网关服务系统》 - 以解决各类业务接口(http/rpc)便捷转换为MCP协议接口而设计实现

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/ai-mcp-gateway/ai-mcp-gateway-4-1-06.png" width="850px">      
</div>

- 项目：<https://t.zsxq.com/NDWBI>
- 介绍：本项目是 AI Agent 智能体，关于 MCP 协议对接的通用网关服务项目，以解决各类业务接口便捷转换为 MCP 协议而设计实现。通过这样的配置，可以大大的简化从普通http、rpc接口到 MCP 协议的转换操作。这样的项目，也是每个互联网公司在做 AI Agent 智能体时，必备的基础设施项目。

#### 2.6 Auto Mobile

《AI Agent 脚手架 + 场景应用》- 综合 Spring AI、LangChain4j + Google ADK（a2a、mcp、skills），打造全新智能体架构方案。

<div align="center">      
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-5/5-9/images/ai-agent-scaffold-5-9-03.png" width="850px">      
</div>

- 项目：<https://t.zsxq.com/UIlv5>
- 介绍：本套 AI Agent 综合智能体脚手架 项目，主要为降低智能体开发门槛、提升业务系统集成效率而构建。项目涵盖了：工程脚手架自动生成、智能工作流编排、多模态交互（文本/绘图/动作） ，以及手机自动化网关控制等核心功能和场景方案。

---

### Md Ai Trae (`docs/md/ai/trae.md`)

---
title: Trae.ai
lock: need
---

# Trae.ai - 真好用，码农必备工具！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

有人说程序员这个行业👨🏻‍💻总是在革自己的命，一个个编码 AI 工具的出现，是不已经不需要那么多初级 CRUD 程序员了🤔。但恰恰相反，AI 工具的出现，是把初级程序员，迅速培养到了高级工程师！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-nas-01.gif" width="200px">
</div>

`其实 AI 让程序员更牛！`

以前初学编程看不懂的代码，现在使用AI能动态做解释和提供案例，以前跨语言（java->vue/react）不能做的事情，现在可以搞了。以前不能写的插件（IntelliJ IDEA、谷歌浏览器），现在能实现了。以前写不出的高级感代码，现在随手就拿到全球最优秀的编码方案。

今天介绍一款 AI 开发工具 [Trae.ai](https://www.trae.ai/) ，让刚入门编程的找到学习方法，让初级工程也能写出优秀的代码，让高级研发嘎嘎提高效率！

>文末提供了 AI 应用开发实战项目，想提高  AI 应用编程能力的伙伴，可以获取学习项目。

## 一、软件下载

官网地址：[https://www.trae.ai/](https://www.trae.ai/) 

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-01.png" width="650px">
</div>

- Trae 是一个自适应的 AI IDE，它可以改变您的工作方式，与您协作以更快地运行。
- 在使用的时候，你可以一个工程同时在 IntelliJ IDEA 打开，也使用 Trae 打开。😂 `因为习惯 IntelliJ IDEA，各类调试还是很舒服的。`

> 同类软件 [Cursor](https://www.cursor.com/cn)，不过这个想使用好的模型得付费，Trae 是不需要付费的！

## 二、使用体验

### 1. 提问代码

**拖拽代码/文件夹/工程**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-02.png" width="750px">
</div>

**添加代码到对话**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-03.png" width="750px">
</div>

**通过#号，选择要对话的内容**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-04.png" width="750px">
</div>

> 之所以分享这个软件，也是因为很多小白初学编程，拿到一个项目不知道从哪里看。现在你有了这个软件，就可以非常简单的对工程的代码进行提问了。也不需要复制到任何 AI 对话工具了，并且这套软件是免费的。

### 2. 生成代码 - 后端

这里我们举例，复制掘金发文接口，之后让 Trae.ai 帮我包装；

#### 2.1 复制接口

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-05.png" width="750px">
</div>

#### 2.2 研发设计 - 话术

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-06.png" width="750px">
</div>

**生成话术，类似于研发设计**

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 2.3 编码效果

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-07.png" width="850px">
</div>

- 生成后，代码会直接写入到你说明的文件夹下，创建好相关的类信息。之后你可以点击全部接受，他会审查代码，如果代码有问题还会检修编写。

### 3. 生成代码 - 前端

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-08.png" width="950px">
</div>

- 这是小傅哥实现的一套 AI RAG&MCP 知识库项目，设计的一套页面。这套页面使用了 AI 做了大量的编码。`以前能写前端，但总感觉是屎上雕花，不出活！`这回有 AI 工具，省心多了。
- AI 对于这类既定的，没有复杂的逻辑和各类框架综合使用的，真的描述一句优化UI，它就`苦吃苦吃`的干活了！

> 你发现没，你只要写一些描述，它就能很好的干活了。这是因为 AI Agent 智能体会包括；规划、记忆、召回、工具（MCP），来把需求转换为可以看到的代码。

## 三、实战项目

这是小傅哥最近带着大家做的一套 AI 应用实战项目，《DeepSeek RAG&MCP 增强检索知识库系统》 - 解析文档&Git仓库代码&AI工作流，全程视频手把手教学。

RAG：实现了除普通文档知识解析外，增加了 Git 代码库的拉取和解析，并提供操作接口。为工程师做项目开发时，`需求分析`、`研发设计`、`辅助编码`、`代码评审`、`风险评估`、`上线检测`等，做工程交付提效。

MCP：用不了多久，各大互联网企业都将大量的推进落地，自有 MCP 服务的实现，用于增强企业 AI 应用的提效能力。因为 MCP 的加入，可以让你；一条命令`帮研发`，调用应用系统日志、排查系统CPU负载、自主选择是否调度数据库信息。也可以一条命令`帮运营`，搞定复杂的SQL执行、导出报表、分析数据、完成促活营销券的自动化配置上架。这就是 MCP的魅力！👍🏻

**RAG + MCP = 智能AI工作流，如智能客服，智能编码助手，智能运维工程师等。**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-trae-09.png" width="650px">
</div>

```java
@Test
public void test_weixinNotice_chatMemory() {
    System.out.println("\n>>> ASSISTANT: " + chatClient
            .prompt("""
                    我需要你帮我生成一篇文章，要求如下；
                            
            1. 场景为互联网大厂java求职者面试
            2. 面试管提问 Java 核心知识、JUC、JVM、多线程、线程池、HashMap、ArrayList、Spring、SpringBoot、MyBatis、Dubbo、RabbitMQ、xxl-job、Redis、MySQL、Linux、Docker、设计模式、DDD等不限于此的各项技术问题。
            3. 按照故事场景，以严肃的面试官和搞笑的水货程序员谢飞机进行提问，谢飞机对简单问题可以回答，回答好了面试官还会夸赞。复杂问题胡乱回答，回答的不清晰。
            4. 每次进行3轮提问，每轮可以有3-5个问题。这些问题要有技术业务场景上的衔接性，循序渐进引导提问。最后是面试官让程序员回家等通知类似的话术。
            5. 提问后把问题的答案，写到文章最后，最后的答案要详细讲述出技术点，让小白可以学习下来。
                            
            根据以上内容，不要阐述其他信息，请直接提供；文章标题、文章内容、文章标签（多个用英文逗号隔开）、文章简述（100字）
                            
            将以上内容发布文章到CSDN。
                    """)
            .advisors(advisor -> advisor
                    .param(CHAT_MEMORY_CONVERSATION_ID_KEY, "1001")
                    .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
            .call()
            .content());
                       
                       
    System.out.println("\n>>> ASSISTANT: " + chatClient
            .prompt("""
                     之后进行，微信公众号消息通知，平台：CSDN、主题：为文章标题、描述：为文章简述、跳转地址：从发布文章到CSDN获取 url
                    """)
            .advisors(advisor -> advisor
                    .param(CHAT_MEMORY_CONVERSATION_ID_KEY, "1001")
                    .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
            .call()
            .content());
}
```

- 两轮对话，发文到CSDN，之后推送消息到公众号平台。这两轮对话是配置有记忆功能的，所以可以衔接上下文。
- 这样的技术，还是非常有必要积累的，因为很多中大厂也都开了 AI 开发工程师的岗位。

---

### Md Ai Walicode (`docs/md/ai/walicode.md`)

---
title: WaLiCode
lock: need
---

# 平替 trae.ai/codex，又一个嘎嘎好用 AI IDE ！重点 - 支持各类渠道配置！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=116439918839670&bvid=BV1Zkd2BvExi&cid=37678287665&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥！

我自己做了个 **WaLiCode，平替市面 AI IDE（trae.ai/codex）** [https://walicode.xiaofuge.cn](https://walicode.xiaofuge.cn) 为什么不用他们的了？🤔

首先我个人是 Trae.ai 的付费用户，还是2个账户开年卡的付费用户，但也不够用！`因为他变了！`先是下掉了 Claude Code 模型（不准了以后要多次提问），后是调整了每个月给600次对话，为 $20 + 赠送额度的 Token 消耗，基本1-2天就把一个月的额度干没了（😂也是我用的猛？）。所以，不够用，根本不够用！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-01.png" width="650px"/>
</div>

**不够用咋办，买额度？**

虽然市面有一些 `coding/token plan`，但基本这些套餐都没有 GPT、Google、Claude 模型，总感觉用起来，劲不够大。想用 CPAMC、CC-Switch，或者自己 API ，这些 AI IDE 又都不允许配置。**真实条条大路，条条卡的死死的。**

所以我的诉求就是，自研一款 AI IDE 工具（`瓦力Code`）；允许各类 API 配置（支持 curl 标准协议，直接导入使用），并可添加 MCP、Skills 服务，同时深度设计一款上下文服务（避免对话多了成傻子了）。最终让这款 AI IDE 工具，成为我手边最为值得使用的 AI 提效工具。

接下来，小傅哥就为你介绍下，如何爽用这款软件，如何使用 AI IDE 提效。总结为，它可以帮助你；分析项目、编程开发、绘制图稿、提问代码（辅助学习）、面试总结（八股）等等，所有你脑洞打开的东西，都可以帮你处理。

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/product-walicode-00.png" width="300px"/>
</div>

>产品优势；支持配置任何渠道商（不限制配置）、有图形界面可以与代码对话方式完成功能开发（节省Token）。也可以扫码加入群关注产品动态和大家使用效果（已有300人+）。

## 一、软件安装

### 1. 软件信息

- 官网：[https://walicode.xiaofuge.cn/](https://walicode.xiaofuge.cn/)
- 下载：[https://drive.weixin.qq.com/s?k=ACMA4AfQABUV1xP9Uo#/](https://drive.weixin.qq.com/s?k=ACMA4AfQABUV1xP9Uo#/)
- 仓库：[https://github.com/fuzhengwei/WaLiCode](https://github.com/fuzhengwei/WaLiCode) - `方便提交 issue，下载 Release 包。`

你可以通过多个渠道，包括网盘、仓库（Release），获取软件安装包。首次安装完成后，后续会通过自动检查版本的方式，来提醒你可以安装最新版本。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-02.png" width="550px"/>
</div>

### 2. 安装完成

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-00.png" width="950px"/>
</div>

- 产品功能如图所示，你可以参考后使用。基本这些内容，和市面的各类 AI IDE 的设计也都是类似的，没有什么迁移使用成本。
- 下载安装后，就可以按照下面的环境配置进行操作了。最主要的就是配置一个 LLM，WaLiCode 支持各类渠道配置，不限制！

> 产品迭代速度很快，陆续的完善各项功能。也因为是咱们自己的东西，大家提到的优化点以及新的功能诉求，都可以很快的支持。

## 三、环境配置

### 1. 模型配置

#### 1.1 walicode 平台

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-01.png" width="500px"/>
</div>

- 首先，WaLiCode 平台，默认提供了 claude-opus-4-6、gpt-5.4、gpt-5.1、gpt 4.1 模型，速度很快，很方便使用。
- 之后，也支持多厂家模型灵活配置；自定义 OpenAI 格式的各类大模型接口，无论是智谱、火山引擎还是本地部署的模型，均可一键接入，满足不同场景的开发需求。也支持你自己做号池（CPAMC）。

#### 1.2 其他供应商

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-02.png" width="950px"/>
</div>

- 智谱：`https://open.bigmodel.cn/api/paas/v4`
- Anthropic：`https://ark.cn-beijing.volces.com/api/coding/v1`
- CPAMC：`https://cpa.taian.liujunjiang.cn:1111/v1`
- deepseek：`https://api.deepseek.com`
- 豆包：`https://ark.cn-beijing.volces.com/api/coding/v1`
- xiaomimimo：`https://token-plan-cn.xiaomimimo.com/v1`
- Ollama：`http://127.0.0.1:11434`

### 2. skill 技能

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-04.png" width="650px"/>
</div>

- 允许添加各类 skills 技能，包括；Git 远程加载共享技能包、本地直接上传 zip 压缩包。添加后的技能，可以点击更新、修改和删除操作。
- 技能增加清单默认、AI 自动和关闭操作，以便于用户自主选择。

> skills 非常有用，你可以让 AI IDE 基于 skills 规范，把工程“蒸馏”，之后配置到 skills。这样他会更加理解你的工程。

### 3. mcp 配置

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-05.png" width="650px"/>
</div>

- MCP 配置与生态集成，通过 Model Context Protocol 接入丰富的外部工具生态，一键配置数据库、文件系统、API 服务等扩展能力。

>像是公司里的很多业务系统，如果需要做系统日志分析，监控故障排查，那么都可以通过 MCP 方式进行接入使用。此外对于你已经对特定问题可以有固定的流程（SOP）标准排查，那么又可以提炼为 skills 技能。

## 四、场景技巧

WaLiCode 这种 AI IDE 相对于 CLI（OpenCode、Claude Code）的优势在于，我们可以讲对话的工程、模块、类、代码片段，以及外部的文件（产品PRD）、URL（在线文档），都可以填入对话框。让上下文对话更加精准（节省Token）。

### 1. 辅助开发

#### 1.1 工程分析（+流程转代码）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-10.png" width="950px"/>
</div>

> 我是一个编程的初学者，请根据项目内容，深度分析后，帮我绘制下架构图，draw.io 文件格式。帮助我理解项目。尤其是核心重点流程。

只是一个非常重要的功能，可以非常有效的帮助用户分析系统工程。将代码逻辑转换为可以便于理解的图稿形式，对于你所有不了解的流程，可以让它分析后产生流程图。

此外，不用局限于流程图，还可以出 UML 图、时序图等等。按照你的诉求，帮你直接做出来。

之后 **思路打开**，这个过程还可以反过来。你可以先让 AI 根据产品功能诉求，设计功能流程的 UML 时序图。之后把时序图添加到对话，让 AI 根据时序图流程，完成功能代码开发（~~以后让产品经理自己写代码吧！~~）。

#### 1.2 页面对接

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-07.png" width="850px"/>
</div>

你可以把要`修改/新增`的逻辑设计的，`模块`，`文件`，`类`，都加入到对话框中，这样的描述会让 AI 识别的更加准确。与 CLI 命令相比，在复杂的业务流程中，代码的开发迭代，你可以更加清楚明了的指出。最终开发的代码也会让你更加有信息。

#### 1.3 接口对接

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-09.png" width="850px"/>
</div>

如果是需要做一些接口开发，我们可以复制 curl 格式，告诉 AI IDE 要在哪个文件夹开发什么接口。它可以非常方便的帮助我们实现这些内容。

#### 1.4 补全注释

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-11.png" width="850px"/>
</div>
程序员开发代码，既希望别人写注释，自己又不爱写注释。那么这个工作就可以让 AI IDE（walicode）来完成，它可以引入 swagger 按照非常标准的格式结构协议，帮你写注释。同时还能给你提供出一套 Swagger OpenAPI 协议结构，以后导出接口文档，也可以让别人看懂了（包括 AI 也可以看的更明白了）。

> 打开思路，你可以在各个场景使用 WaLiCode 帮你提效。添加 Swagger，对接工程接口，补全注释信息。

#### 1.5 AI Shell

##### 1.5.1 基础功能（shell、目录、sftp）

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-03.png" width="950px"/>
</div>

- 你可以切换到左侧目录运维下的 SSH 服务，之后【新增】连接配置信息。连接后就可以使用基础的 SSH 能力了，shell、目录、sftp 都是完整具备的。
- 此外，还有命令辅助能力，这会极大的方便小白伙伴一边学习，一边使用脚本。

##### 1.5.2 智能操作

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-04.png" width="950px"/>
</div>

- 你可以通过对话，直接询问 AI；`分析 ai-draw-io-front 运行日志`、`检查 docker 里安装的软件`，都是可以直接帮你操作的。使用起来非常方便，小白伙伴用几次，都成运维大佬了！
- 提示，项目工程编码、SSH 服务，是可以共用的，比如选择了工程代码，在通过 @的方式选择的服务器，告诉上传脚本，也是可以直接上传进去的。很丝滑！

##### 1.5.3 联动操作（工程+shell+sftp）

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-05.png" width="950px"/>
</div>

- 通过 ai 对话框，选择要上传的文件夹、文件，到指定的云服务器，那么他就可以直接上传进去了。
- 执行中，会有一些命令提示，你可以选择加入到白名单，加入的命令可以在设置里维护。

##### 1.5.4 自动部署+ssl申请

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-08.png" width="950px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-09.png" width="950px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-10.png" width="950px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-11.png" width="950px"/>
</div>

准备内容；

1. [http://618.gaga.plus](http://618.gaga.plus) - 2c4g 服务器
2. LLM 大模型套餐，gpt-5.4（本案例测试使用）

话术过程；

1. 服务器有安装docker吗，如果没有请帮我安装。
2. 安装 portainer
3. 帮我部署个 nginx 转发到 9000 这样是不更安全
4. 你可以获取到 免费的 ssl 吗，来做 https
5. 已配置域名 portainer.gaga.plus （帮我分析了域名还配置了其他ip）
6. 你来访问验证试试 https://portainer.gaga.plus/ 验证下（帮我分析了443没开放）

过程中，发了2次；继续、配置好了，继续。

>全程帮你完成服务器的部署、nginx转发、ssl申请。非常方便。

#### 1.6 活动追踪

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-06.png" width="950px"/>
</div>

该功能的主要目的在于，我们在使用 AI 执行一些列动作，完成用户诉求的过程中，希望可以看到 AI 都在做什么。从分析代码文件，到修改和编译文件，你可以到每一个步骤对文件的操作过程。这样可以让你更有信息应对复杂项目的处理。

#### 1.7 任务队列

<div align="center">
	<img src="https://bugstack.cn/images/article/product/software/walicode-v0.3.0-07.png" width="500px"/>
</div>

该功能的主要目的在于，提前预设添加好一些待执行任务，之后可以选择执行间隔、定时执行开始时间，这样你在出门后，也可以把要干的活提前分配好，让 AI 不间断工作。甚至是夜晚你已经睡觉了，它还可以继续哇哇的干活！

### 2. 面试帮助

#### 2.1 八股整理

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-12.png" width="850px"/>
</div>

>基于该项目的架构设计，核心流程，技术选型，功能方案等，给我出一份面试八股问题。面试官，最容易考察的问题点。我需要题目以及解答参考。整理好md放到工程下。

你可以基于项目工程，让 AI IDE 帮你出一份面试八股问题。但一定要用好一些模型，否则给出的八股质量不高。

#### 2.2 综合面试（简历、招聘、项目）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/product-walicode-user-guide-08.png" width="850px"/>
</div>

- 首先，当你做完一个项目以后，你可以把自己的简历（最好md格式），以及你要面试的公司（岗位职责信息）+ 其他汇总资料，都放到工程下。
- 之后，你可以把这些资料加入到对话，核心的目的在于；让 AI IDE 基于你的资料，以及打开的当前简历，在配和当前项目，对你进行面试总结整理。（注意好的模型，会给出更有用的答案）

> 好啦，接下来你可以打开思路，让 AI IDE 在各个场景帮你提效。而且这类工具也必须是熟练使用的，各个公司里也会要求研发人员使用 AI IDE 的编码要有一定比例的，面试的时候甚至还会说你直接用 AI IDE 完成一个功能开发。

---

### Md Ai Xfg Skills Free Token Plan V2 (`docs/md/ai/xfg-skills-free-token-plan-v2.md`)

# 自建「中转站」 + 2 套 skills，让智能体自己找“粮”（token）吃！又能生成视频！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

一会这个厂家免费送Token，一会那个厂家免费到月底，再整上一堆的个人newapi。好家伙，本地的 `OpenClaw`、`WorkBuddy`、`Claude Code`、`Codex`、`WaliCode`...，哪个不是配置了一堆的 LLM 大模型地址（`✋🏻手都配麻了`）！主要还不稳，一会这个能用，一会哪个不能用。搞滴，兄弟们，群里天天喊：**“说啊！，哪里啊！”**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-01.png" width="150px"/>
</div>
**Agnes LLM 你快点来，我等你！**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-20.png" width="150px"/>
</div>

两周还没到，买的一堆 coding plan、token plan 也都吸干净了。 好在发现了 `Agnes AI`，它把核心全模态模型 API 免费开放！编码、画图、做视频都没问题；

- 文本模型：`Agnes-2.0-Flash`
- 图片模型：`Agnes-Image-2.1-Flash`
- 视频模型：`Agnes-Video-2.0`

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-21.png" width="550px"/>
</div>

经过一周的使用体验，确实还挺稳的。当然众所周知，LLM 这东西用的最多的还是程序员，所以能写代码，能把代码写好很重要。在这些天高强度的编码体验后，确实还挺让惊喜的。已经在 `OpenClaw`、`WaliCode`、`Codex`、`Claude Code（CCSwitch）`全都安排上了！

**但**，如果你想吃的更香，可以这么干！

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-22.png" width="200px"/>
</div>

`我提一个方案，大家来研究。`

我们免费的 LLM 很多呀，给的 Token 也很足。写代码、画图、做视频，都囊括了。那这，如果我做个 Skills，**不**！做2个Skills。一个负责统一的管理 LLM API 以及动态的分发 APIKey，另外一个负责画图和生视频，减去中间过程复杂操作，让 Skills 搞定画图和视频生成中的地址处理，提示词完善。那这样一来，我不成了免费大模型的东家了！

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-29.png" width="650px"/>
</div>

这2套skills，一套负责自动化配置、检查渠道，自动化创建 ApiKey。另外一套负责图片和视频自动化的生产。简直不要太舒服！如果你有一个小组/团队/公司，那大家可就都享福了！接下来，小傅哥就告诉你怎么安装使用。

> 接下来，小傅哥就带着你使用 xfg-skills-free-token-free +  xfg-skills-agnes + [agnes](https://agnes-ai.com/doc/quick-start)（免费1M全模态上下文模型），干起来！

## 一、免费模型（体验效果）

咱们干东西，上来先搞一下 API 看看最本质的东西咋样。

#### 1. 写代码

```java
curl https://apihub.agnes-ai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -d '{
  "model": "agnes-2.0-flash",
  "messages": [{"role": "user", "content": "1+1"}]
}'
```

- 你可以自己申请 ApiKey 替换后进行测试。这部分重点在后面体现模型编码使用

#### 2. 文生图

```java
curl https://apihub.agnes-ai.com/v1/images/generations \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-image-2.1-flash",
    "prompt": "绝美东方年轻女生，22 岁，鹅蛋脸，精致淡柳叶眉，下垂无辜小鹿眼，浅琥珀色瞳孔，长睫毛，自然淡卧蚕，小巧挺翘鼻梁，薄唇淡豆沙色唇釉，冷白皮，柔和原生骨相，微卷黑长直发披在肩头；宽松米白色针织吊带，细锁骨，肩颈线条流畅；窗边柔光侧逆光，薄纱窗帘透光，发丝发光，浅景深虚化背景，室内原木极简卧室，温柔氛围感，电影级光影，8K 超清，超写实人像，皮肤纹理细腻真实，单反 50mm f1.4 拍摄，高清五官特写，画质锐利，色彩柔和低饱和",
    "size": "1024x768",
    "extra_body": {
      "response_format": "url"
    }
  }'
```

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-23.png" width="600px"/>
</div>

- 提示词1 `日系氧气少女，元气笑脸，浅浅梨涡，短发内扣，浅栗色头发，日系淡妆，白衬衫百褶短裙，夏日街角街边，阳光树荫光斑，胶片质感，颗粒轻微，日系小清新色调，半身人像，自然动态，松弛姿态，高清写实，肤色通透`
- 提示词2 `90 年代香港复古御姐，大波浪复古卷发，红唇明艳，细长猫眼眼线，修身丝绒红裙，复古胶片闪光灯光影，昏暗酒吧背景，颗粒胶片质感，冷艳气场，眼神疏离，轮廓立体，高级人像摄影，4K 超清，复古色调浓郁`
- 提示词3 `绝美东方年轻女生，22 岁，鹅蛋脸，精致淡柳叶眉，下垂无辜小鹿眼，浅琥珀色瞳孔，长睫毛，自然淡卧蚕，小巧挺翘鼻梁，薄唇淡豆沙色唇釉，冷白皮，柔和原生骨相，微卷黑长直发披在肩头；宽松米白色针织吊带，细锁骨，肩颈线条流畅；窗边柔光侧逆光，薄纱窗帘透光，发丝发光，浅景深虚化背景，室内原木极简卧室，温柔氛围感，电影级光影，8K 超清，超写实人像，皮肤纹理细腻真实，单反 50mm f1.4 拍摄，高清五官特写，画质锐利，色彩柔和低饱和`
- 提示词4 `古典江南古装美人，温婉雅致，丹凤眼，桃花眼，樱桃小口，珍珠耳坠，水墨眉妆，乌黑盘发配玉簪流苏，浅青色齐胸襦裙，刺绣海棠花纹，站在江南园林荷花池边，湖面薄雾，垂柳摇曳，古风烟雨柔光，工笔质感 + 写实结合，仙气飘逸，发丝随风飘动，衣袂褶皱细腻，8K，电影光影，细节拉满，国风配色雅致`

#### 3. 生视频

```java
curl -X POST https://apihub.agnes-ai.com/v1/videos \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-video-v2.0",
    "prompt": "整体剧情：外卖员接单遭遇地址混乱暴怒质问，另一方骑手暗中邀约碰面，幕后西装大佬准备抛出交易方案，三段镜头无缝转场，港片黑帮暗线外卖题材短剧。完整提示词：长剧情连贯港风犯罪短剧，三段镜头无缝转场，24 帧 4K 胶片电影质感，统一港片色调。第一段：楼道里甄子丹外卖骑手暴怒打电话嘶吼追问配送地址，镜头轻微晃动；硬切转场第二段：暗巷里邹兆龙红帽骑手接起电话，低声邀约对方前来碰面，暗光悬疑氛围；淡入转场第三段：红砖房间内西装大佬梁家辉端坐，从容准备抛出交易方案，大佬压迫气场拉满；全程人物口型匹配对应字幕台词，镜头运镜流畅连贯，光影色调全程统一，真人实拍电影效果，无 AI 扭曲面部，人物五官保持演员原生样貌，动态自然流畅，完整 15 秒连贯短视频。",
    "height": 768,
    "width": 1152,
    "num_frames": 121,
    "frame_rate": 24
  }'
```

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-24.png" width="600px"/>
</div>

更多细节，详细可见文档；[https://agnes-ai.com/doc/quick-start](https://agnes-ai.com/doc/quick-start)

## 二、技能安装

### 1. 技能介绍

#### 1.1 渠道技能

地址：[https://github.com/fuzhengwei/xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan)

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-03.png" width="650px"/>
</div>

- 首先，该技能先是分析了 one-api 源码，拿到所有服务接口，之后由智能体工具（WaliCode）按照技能创建模板（[xfg-skills-template](https://github.com/fuzhengwei/xfg-skills-template)），根据我的诉求（自动化的完成LLM渠道的维护和ApiKey的提供），制作的一套 xfg-skills-free-token-plan 技能。现技能源码全部开放，你可以学习，下载，使用。
- 之后，你可以在任何一个，支持 skills 技能配置的智能体软件上安装此技能，并与它对话，自主的完成渠道配置以及 ApiKey 的下发使用。

#### 1.2 模型技能（增强文生视频 + 文生图）

地址：[https://github.com/fuzhengwei/xfg-skills-agnes](https://github.com/fuzhengwei/xfg-skills-agnes)

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-25.png" width="650px"/>
</div>

- 这是 Agnes AI 图像与视频生成技能，兼容 Agent Skills 开放标准。直接配置到智能体软件就可以在各个场景做视频的生成了。使用过程中，技能会提示你如何操作。

### 2. 技能配置

以 OpenClaw、WaliCode 举例，其他的也都是类似的操作；

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-05.png" width="750px"/>
</div>

1. 下载本技能 [https://github.com/fuzhengwei/xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan)、[https://github.com/fuzhengwei/xfg-skills-agnes](https://github.com/fuzhengwei/xfg-skills-agnes) 或克隆到本地
2. 将 `xfg-skills-free-token-plan`、`xfg-skills-agnes` 目录复制到 WaLiCode Skills 目录：
   - macOS/Linux：`~/.walicode/skills/`
   - Windows：`%USERPROFILE%\.walicode\skills\`
3. 回到 WaLiCode 的 Skills 配置，点击导入即可。

> skills 脚本依赖于 python3 环境，一般 Mac 电脑都都是有的，Windows 电脑如果没有可以让智能体软件，帮你安装即可。

## 三、场景体验

### 1. 获取KEY

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-09.png" width="650px"/>
</div>

上去就是一句 `给爷来个 key` 之后你就可以拿到一个可以使用的 ApiKey 了。还有一个测试的 curl 把这个配置到你的智能体就可以使用了。

### 2. 生成图片

#### 2.1 人物图

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-27.png" width="400px"/>
</div>

随手生成个图片，直接在工具了就可以使用了。

#### 2.2 设计图

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-28.png" width="600px"/>
</div>

这次我只是给了一个简单的描述，就可以做出对应的 UI 设计。有了这些设计，还是很有利于我们做一些软件实现的。

### 3. 干个视频

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-26.png" width="600px"/>
</div>

任何一款智能体工具，安装好软件后，写好提示词，哇哇的就给出视频了。现在你不只是程序员，还是电影设计师，以后想自己搞点啥，都是美滋滋的。

## 四、深度编码

**我来啦，汤泥！**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-18.png" width="550px"/>
</div>

如果你暂时不走 [xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan) 也可以直接配置模型开干！

- 软件：[https://walicode.xiaofuge.cn/](https://walicode.xiaofuge.cn/)

- BaseUrl：https://apihub.agnes-ai.com/v1
- APIKey：[https://platform.agnes-ai.com/settings/apiKeys](https://platform.agnes-ai.com/settings/apiKeys) - 直接申请就可以使用，模型能力很强！
- 模型：`agnes-2.0-flash`

### 1. 图片识别

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-14.png" width="350px"/>
</div>

- 具备图片识别能力的多模态模型，才好做开发。世界首富也可以识别出来，很可以。

### 2. 绘制流程

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-16.png" width="850px"/>
</div>

- 开发中还需要绘图，把代码流程绘制出来。这个模型很赞！

### 3. 辅助开发

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-19.png" width="850px"/>
</div>

- 长时间运行也很稳定，不错！

### 4. 智能运维

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-17.png" width="850px"/>
</div>

- 运维能力分析系统，效果很赞。也可以使用模型对服务器上的项目进行压测。

---

### Md Ai Xfg Skills Free Token Plan (`docs/md/ai/xfg-skills-free-token-plan.md`)

# 自建「中转站」 + skills，让智能体自己找“粮”（token）吃！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

一会这个厂家免费送Token，一会那个厂家免费到月底，再整上一堆的个人newapi。好家伙，本地的 `OpenClaw`、`WorkBuddy`、`Claude Code`、`Codex`、`WaliCode`...，哪个不是配置了一堆的 LLM 大模型地址（`✋🏻手都配麻了`）！主要还不稳，一会这个能用，一会哪个不能用。搞滴，兄弟们，群里天天喊：**“说啊！，哪里啊！”**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-01.png" width="150px"/>
</div>
**咋整，这滴想想办法呀🤔！**

嘿嘿，有了；自己坐庄，把这些免费的 Token 给它囊括起来。—— `技术架构师，永远都是有问题就有方案。`

Github 上有个开源项目叫 [**one-api**](https://github.com/songquanpeng/one-api) 现已是 `34.9k Star⭐️`的明星项目。它是一套最早的 LLM API 管理 & 分发系统，基本囊括了市面90%的大模型对接。完成模型配置后，可以统一分发、管理和使用 ApiKey 进行大模型通信。

也就是说 one-api 承担的是，把你拿到手的各类 LLM API 渠道都配置进来，之后以映射的方式用自定义的 `auto-model`/`AutoModel` 模型名称进行使用，屏蔽掉各类模型的名称差异。那么本地这一堆的软件，也就只是需要配置一个统一的 baseUrl、model、apiKey 即可。

但是，让每个人都自己维护 one-api 的渠道配置（还得映射模型），ApiKey 的创建，也麻烦呀。所以，他来了 [xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan)  自由的，免费的，Token Plan 技能！

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-02.png" width="550px"/>
</div>
自动化配置、检查渠道，自动化创建 ApiKey，简直不要太舒服！如果你有一个小组/团队/公司，那大家可久都享福了！接下来，小傅哥就告诉你怎么安装使用。

> 接下来，小傅哥就带着你使用 one-api + xfg-skills-free-token-free + [agnes](https://agnes-ai.com/doc/quick-start)（免费1M上下文模型），干起来！

## 一、技能介绍

### 1. 技能工程

地址：[https://github.com/fuzhengwei/xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan)

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-03.png" width="650px"/>
</div>

- 首先，该技能先是分析了 one-api 源码，拿到所有服务接口，之后由智能体工具（WaliCode）按照技能创建模板（[xfg-skills-template](https://github.com/fuzhengwei/xfg-skills-template)），根据我的诉求（自动化的完成LLM渠道的维护和ApiKey的提供），制作的一套 xfg-skills-free-token-plan 技能。现技能源码全部开放，你可以学习，下载，使用。
- 之后，你可以在任何一个，支持 skills 技能配置的智能体软件上安装此技能，并与它对话，自主的完成渠道配置以及 ApiKey 的下发使用。

### 2. 免费渠道（agnes 👍🏻）

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-04.png" width="950px"/>
</div>

- 地址：[https://github.com/fuzhengwei/xfg-skills-free-token-plan/blob/main/data/channels.csv](https://github.com/fuzhengwei/xfg-skills-free-token-plan/blob/main/data/channels.csv)
- 说明：小傅哥这里内嵌了一些渠道，像是免费的 agnes-2.0-flash 用着也还很不错（支持1M上下文）。这些内嵌的渠道，你可以通过对话的方式获取 Key，拿到渠道配置信息后，继续使用技能对话，让配置到你的渠道里就可以了。

**以下是对  Agnes LLM 大模型的验证，写代码、文生图、文生视频，确实挺厉害；**

#### 2.1 写代码

```java
curl https://apihub.agnes-ai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -d '{
  "model": "agnes-2.0-flash",
  "messages": [{"role": "user", "content": "1+1"}]
}'
```

- 你可以自己申请 ApiKey 替换后进行测试。

#### 2.2 文生图

```java
curl https://apihub.agnes-ai.com/v1/images/generations \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-image-2.1-flash",
    "prompt": "90 年代香港复古御姐，大波浪复古卷发，红唇明艳，细长猫眼眼线，修身丝绒红裙，复古胶片闪光灯光影，昏暗酒吧背景，颗粒胶片质感，冷艳气场，眼神疏离，轮廓立体，高级人像摄影，4K 超清，复古色调浓郁",
    "size": "1024x768",
    "extra_body": {
      "response_format": "url"
    }
  }'
```

- 提示词1 `日系氧气少女，元气笑脸，浅浅梨涡，短发内扣，浅栗色头发，日系淡妆，白衬衫百褶短裙，夏日街角街边，阳光树荫光斑，胶片质感，颗粒轻微，日系小清新色调，半身人像，自然动态，松弛姿态，高清写实，肤色通透`
- 提示词2 `90 年代香港复古御姐，大波浪复古卷发，红唇明艳，细长猫眼眼线，修身丝绒红裙，复古胶片闪光灯光影，昏暗酒吧背景，颗粒胶片质感，冷艳气场，眼神疏离，轮廓立体，高级人像摄影，4K 超清，复古色调浓郁`
- 提示词3 `绝美东方年轻女生，22 岁，鹅蛋脸，精致淡柳叶眉，下垂无辜小鹿眼，浅琥珀色瞳孔，长睫毛，自然淡卧蚕，小巧挺翘鼻梁，薄唇淡豆沙色唇釉，冷白皮，柔和原生骨相，微卷黑长直发披在肩头；宽松米白色针织吊带，细锁骨，肩颈线条流畅；窗边柔光侧逆光，薄纱窗帘透光，发丝发光，浅景深虚化背景，室内原木极简卧室，温柔氛围感，电影级光影，8K 超清，超写实人像，皮肤纹理细腻真实，单反 50mm f1.4 拍摄，高清五官特写，画质锐利，色彩柔和低饱和`
- 提示词4 `古典江南古装美人，温婉雅致，丹凤眼，桃花眼，樱桃小口，珍珠耳坠，水墨眉妆，乌黑盘发配玉簪流苏，浅青色齐胸襦裙，刺绣海棠花纹，站在江南园林荷花池边，湖面薄雾，垂柳摇曳，古风烟雨柔光，工笔质感 + 写实结合，仙气飘逸，发丝随风飘动，衣袂褶皱细腻，8K，电影光影，细节拉满，国风配色雅致`

#### 2.3 生视频

```java
curl -X POST https://apihub.agnes-ai.com/v1/videos \
  -H "Authorization: Bearer sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "agnes-video-v2.0",
    "prompt": "A cinematic shot of a cat walking on the beach at sunset, soft ocean waves, warm golden lighting, realistic motion",
    "height": 768,
    "width": 1152,
    "num_frames": 121,
    "frame_rate": 24
  }'
```

更多细节，详细可见文档；[https://agnes-ai.com/doc/quick-start](https://agnes-ai.com/doc/quick-start)

> 接下来，我们要把这套免费的 API 配置到技能里，感受下它是否夯爆了💥！如果着急验证模型，也可以直接跳到第五部分，做模型的配置使用。

## 二、技能安装

以 OpenClaw、WaliCode 举例，其他的也都是类似的操作；

### 方式一：从 GitHub 克隆（推荐）

```bash
# 克隆仓库到 OpenClaw Skills 目录
git clone git@github.com:fuzhengwei/xfg-skills-free-token-plan.git ~/.qclaw/skills/xfg-skills-free-token-plan
```

克隆后重启 OpenClaw 即可生效，对话中输入触发词即可使用。

### 方式二：手动安装

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-05.png" width="750px"/>
</div>

1. 下载本技能 [https://github.com/fuzhengwei/xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan) 或克隆到本地
2. 将 `xfg-skills-free-token-plan` 目录复制到 WaLiCode Skills 目录：
   - macOS/Linux：`~/.walicode/skills/`
   - Windows：`%USERPROFILE%\.walicode\skills\`
3. 回到 WaLiCode 的 Skills 配置，点击导入即可。

> skills 脚本依赖于 python3 环境，一般 Mac 电脑都都是有的，Windows 电脑如果没有可以让智能体软件，帮你安装即可。

## 三、服务安装

本身这套 Skills 走到是 one-api 进行渠道配置和Key的管理，你可以在本地（含docker环境）或者在云服务器安装。暂时也可以先不安装，使用小傅哥提供的 one-api（在skills技能里）先玩玩试试。

```java
version: '3'
services:
  mysql:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0
    container_name: oneapi-mysql
    restart: always
    ports:
      - "13306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 12345678
      MYSQL_DATABASE: oneapi
    volumes:
      - /home/ubuntu/data/mysql:/var/lib/mysql
    networks:
      - oneapi-net

  one-api:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/one-api:v0.6.11
    container_name: one-api
    restart: always
    ports:
      - "4000:3000"
    environment:
      SQL_DSN: "root:12345678@tcp(mysql:3306)/oneapi"
      TZ: Asia/Shanghai
    volumes:
      - /home/ubuntu/data/one-api:/data
    depends_on:
      - mysql
    networks:
      - oneapi-net

networks:
  oneapi-net:
    driver: bridge
```

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-06.png" width="850px"/>
</div>
- 通过 docker-compose 执行脚本即可安装完成。
- 如果你使用的是 WaLiCode 那么还可以直接连接云服务器，告诉 AI 在云服务器上配置这套东西就可以了。

## 四、技能配置

### 1. 配置服务（one-api）

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-07.png" width="650px"/>
</div>

> 配置 one-api，地址 http://81.70.245.73:4000，账户 root，密码 12345678

- 选择安装技能，描述如上的话术，把 one-api 渠道配置到技能里。我的这个地址，暂时是可以测试使用的。如果你有部署一个自己的 one-api 记得更改下`地址`、`账户`、`密码`。

- 配置后会自动检测服务是否可用，之后会告诉你怎么使用，如；`给我来个 key`、`添加渠道`、`有哪些渠道`、`检查渠道`

### 2. 配置渠道

你自己的 one-api 安装后，需要找一些 LLM 渠道配置，可以是任何你现在使用的。如果还没有啥 LLM 也可以使用本文的这个免费（效果还不错）的。

#### 2.1 key申请

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-13.png" width="650px"/>
</div>

地址：[https://platform.agnes-ai.com/settings/apiKeys](https://platform.agnes-ai.com/settings/apiKeys) 在这里申请个 ApiKey 配置渠道的时候需要使用。

#### 2.2 key配置

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-08.png" width="650px"/>
</div>

```java
[前面选择上技能]添加渠道 
agnes 
地址；https://apihub.agnes-ai.com 
模型；agnes-2.0-flash 
ApiKey；sk-3f9NQmveWbnL2Pxj4OAdSydKudUUeryh2q498jRuPnNWMJdQ
```

### 3. 获取模型（ApiKey）

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-09.png" width="650px"/>
</div>
上去就是一句 `给爷来个 key` 之后你就可以拿到一个可以使用的 ApiKey 了。还有一个测试的 curl 把这个配置到你的智能体就可以使用了。

### 4. 模型配置

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-10.png" width="650px"/>
</div>

```java
curl http://81.70.245.73:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-bhdR5hX8Asq98z1g5a413fDcC44a4c0186711a7dD020Ec3a" \
  -d '{
  "model": "auto-model",
  "messages": [{"role": "user", "content": "1+1"}]
}'
```

接下来就容易了，各个智能体工具，你就配置这一个地址就行了。以后有啥免费的 LLM 直接扔进去，让 xfg-skills-free-token-plan 帮你维护。

### 5. 检查渠道

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-11.png" width="650px"/>
</div>
当我们配置了越来也多的免费渠道以后，这些渠道可能一段时间就不能用了。那么你可以`检查渠道`，skills 会自动的帮你测试，以及调整渠道的优先级。不可用的时候就会被下掉。

> 咋样，这样用起来是不蛮爽的！赶紧动起来，**你快点来，我等你！**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-12.png" width="150px"/>
</div>

- 技能包：[https://github.com/fuzhengwei/xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan)
- 服务器：[http://618.gaga.plus/](http://618.gaga.plus/)
- 免费（LLM）：[https://platform.agnes-ai.com/settings/apiKeys](https://platform.agnes-ai.com/settings/apiKeys)

## 五、编写代码

**我来啦，汤泥！**

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-18.png" width="550px"/>
</div>

如果你暂时不走 [xfg-skills-free-token-plan](https://github.com/fuzhengwei/xfg-skills-free-token-plan) 也可以直接配置模型开干！

- 软件：[https://walicode.xiaofuge.cn/](https://walicode.xiaofuge.cn/)

- BaseUrl：https://apihub.agnes-ai.com/v1
- APIKey：[https://platform.agnes-ai.com/settings/apiKeys](https://platform.agnes-ai.com/settings/apiKeys) - 直接申请就可以使用，模型能力很强！
- 模型：`agnes-2.0-flash`

### 1. 图片识别

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-14.png" width="350px"/>
</div>

- 具备图片识别能力的多模态模型，才好做开发。世界首富也可以识别出来，很可以。

### 2. 绘制流程

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-16.png" width="850px"/>
</div>

- 开发中还需要绘图，把代码流程绘制出来。这个模型很赞！

### 3. 辅助开发

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-19.png" width="850px"/>
</div>

- 长时间运行也很稳定，不错！

### 4. 智能运维

<div align="center">
	<img src="https://bugstack.cn/images/article/ai/xfg-skills-free-token-plan-17.png" width="850px"/>
</div>

- 运维能力分析系统，效果很赞。也可以使用模型对服务器上的项目进行压测。

---

### Md Devops 2019 08 12 Windows环境下安装Elasticsearch6.2.2 (`docs/md/devops/2019-08-12-windows环境下安装elasticsearch6.2.2.md`)

---
layout: post
category: itstack-demo-any
title: windows环境下安装elasticsearch6.2.2
tagline: by 付政委
tag: [ddd,itstack-demo-any]
excerpt: 在windows环境下安装Elasticsearch 6.2.2
lock: need
---

# windows环境下安装elasticsearch6.2.2

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 前言介绍

在windows环境下安装Elasticsearch 6.2.2

>ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎，基于RESTful web接口。Elasticsearch是用Java语言开发的，并作为Apache许可条款下的开放源码发布，是一种流行的企业级搜索引擎。ElasticSearch用于云计算中，能够达到实时搜索，稳定，可靠，快速，安装使用方便。官方客户端在Java、.NET（C#）、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示，Elasticsearch是最受欢迎的企业搜索引擎，其次是Apache Solr，也是基于Lucene。

## 安装环境
**1、Elasticsearch 6.2.2 下载** [https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2](https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2)


**2、JDK 1.8 （jdk1.7及以下不能支持Elasticsearch）下载** [https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)


**3、安装cmd进入elasticsearch-6.2.2\bin，执行elasticsearch.bat**


**4、启动完成后打开http://localhost:9200 ｛默认端口9200｝**


------------

---

### Md Devops 2019 08 13 Elasticsearch Head插件安装 (`docs/md/devops/2019-08-13-elasticsearch-head插件安装.md`)

---
layout: post
category: itstack-demo-any
title: elasticsearch-head插件安装
tagline: by 付政委
tag: [ddd,itstack-demo-any]
---

# elasticsearch-head插件安装

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 前言介绍
安装Elasticsearch的head插件，用于方便操作Elasticsearch

>elasticsearch-head 是用于监控 Elasticsearch 状态的客户端插件，包括数据可视化、执行增删改查操作等。elasticsearch-head 插件的安装在 Linux 和 Windows 没什么区别，安装之前确保当前系统已经安装 nodejs 即可。

## 安装环境
1. 安装[node.js](https://nodejs.org/en/download/)并配置环境变量PATH{path:D:\Program Files\nodejs\}

- [nodejs下载](https://nodejs.org/en/download/)

- 执行安装，配置环境变量{path:D:\Program Files\nodejs\}

- 查看nodejs版本；node -v


2. 安装elasticsearch-head
- [下载elasticsearch-head](https://github.com/mobz/elasticsearch-head)
- 将elasticsearch-head放到与elasticsearch同层级文件夹下
- 修改elasticsearch-head/Gruntfile.js
```xml
connect: {
	server: {
		options: {
			port: 9100,
			base: '.',
			keepalive: true
		}
	}
}
```
- 修改elasticsearch-6.2.2/config/elasticsearch.yml *添加配置信息
```xml
http.cors.enabled: true
http.cors.allow-origin: "*"
```

3、启动elasticsearch-head
```java
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\user>node -v
v10.16.0

C:\Users\user>D:

D:\>cd D:\Program Files\elasticsearch\head

D:\Program Files\elasticsearch\head>npm run start

> elasticsearch-head@0.0.0 start D:\Program Files\elasticsearch\head
> grunt server

Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:9100

```
**运行结果**


------------

---

### Md Devops 2019 11 23 并不想吹牛皮，但！为了把Github博客粉丝转移到公众号，我干了！ (`docs/md/devops/2019-11-23-并不想吹牛皮，但！为了把Github博客粉丝转移到公众号，我干了！.md`)

---
layout: post
category: itstack-demo-any
title: 并不想吹牛皮，但！为了把Github博客粉丝转移到公众号，我干了！
tagline: by 付政委
tag: [java,itstack-demo-any]
excerpt: 截至到19年11月我已经工作6年了，从业Java但也折腾过C#、搞PHP也弄过中继器、IO板卡，似乎我就是一个很喜欢在技术上折腾的人！与此同时，我也搞了6年的个人小网站，它们的呈现形式多种多样；有用PHP自己捣鼓的技术站用于分享资料、书籍、软件等、有用PHPWIND和DISCUZ的搭建的个人论坛、有用emlog和wordpress搭建的个人博客、也有借用于github+hexo/jekyll的能力组装出的技术博客。但无一例外它们都战死于征战的路上了，亡于；org域名不能备案、PHP服务器瘫痪被清空、http连接被注入恶意内容、定位不准确经常换模式、缺少核心优质内容等等。但！老衲的心依然如春(cun)，因为喜欢干一件事，往往来自于干一了件喜欢的事！
lock: need
---

# 并不想吹牛皮，但！为了把Github博客粉丝转移到公众号，我干了！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 1. 前言介绍
这个！截至到19年11月我已经工作6年了，从业Java但也折腾过C#、搞PHP也弄过中继器、IO板卡，似乎我就是一个很喜欢在技术上折腾的人！与此同时，我也搞了6年的个人小网站，它们的呈现形式多种多样；有用PHP自己捣鼓的技术站用于分享资料、书籍、软件等、有用PHPWIND和DISCUZ的搭建的个人论坛、有用emlog和wordpress搭建的个人博客、也有借用于github+hexo/jekyll的能力组装出的技术博客。但无一例外它们都战死于征战的路上了，亡于；org域名不能备案、PHP服务器瘫痪被清空、http连接被注入恶意内容、定位不准确经常换模式、缺少核心优质内容等等。但！老衲的心依然如春(cun)，因为喜欢干一件事，往往来自于干一了件喜欢的事！

所以！从19年开始我又继续写博客了，注册了新的域名bugstack.cn，备了案、买了服务器、还喊了新的口号；沉淀、分享、成长，让自己和他人都能有所收获！并且将尘封已久的微信公众号找回；结构上调整、内容上布局、粉丝上求关注。在这期间遇到了更大的牛；小灰、王二哥、纯洁的微笑还有松哥等一群伙伴，从他们那学到很多知识，真的非常感谢！

那么！这次的产品功能总结一句话就是；将基于Github+Jekyll搭建的静态博客与我并未开发过的微信公众号功能打通，通过在文章短口令码加锁引导用户到公众号内回复密码可解锁内容，以此来获得粉丝关注，当然如果取消关注了则文章继续锁定。

在多说一句，我理解的产品；其实是使用研发技术力搭建出可以用于承载接收用户在各种设备上所生产的行为数据的一种产品化服务。所以有些产品在做减法，同时也有为丰富的功能做加法，但究其一点我们其实都是在为接收有价值数据服务的。兴衰存亡，皆在核心数据沉淀与运作上！

## 2. 流程设计
为了使博客粉丝主动关注微信公众号，我们在用户初次浏览文章时增加权限验证，给每一个用户都生成一个唯一码引导用户在公众号内回复解锁文章，以此来与微信openid对应。当用户取消关注时则进行删除openid或标记状态，使得用户无法继续浏览文章。其实为了更好的体验，我参照了大牛的方式内容60%的区域可见，其余内容渐进遮挡，蒙胧胧的感觉还挺美。整体流程图如下；


## 3. 功能实现
为了实现本产品功能，我准备了；
1. 微信公众号；bugstack虫洞栈
2. 博客；本文使用的是github+jekyll；地址：https://bugstack.cn
3. 域名；域名申请比较简单，但可能针对不同的服务商还必须备案后才可以使用
4. 友盟；主要为了获取全局的唯一id值，也可以使用其他具备此功能的产品或者自己实现
5. 部署环境；Java云服务器、Mysql云数据库、https证书、Jdk1.8、tomcat1.8，云市场比较多按需购买，如果是本地调试可以使用https://natapp.cn，做免费网络穿透映射

### 3.1 前端
前端主要负责针对发布时设置了look: need的文章，在用户浏览文章检查是否有权限查看全部内容，当用户没有权限时隐藏文章60%内容，并通过页面结尾提醒用户在公众号内回复口令解锁文章。

1. 找到加锁文章容器ID，文章容器选择器：article.post.container.need，拿到选择器ID针对这类文章进行缩小隐藏处理。

```html
<article class="post container need lock" itemscope="" itemtype="http://schema.org/BlogPosting" style="height: 4400px;">

    <div class="row">

        
        <div class="col-md-9 markdown-body">

            <h2 id="前言介绍">前言介绍</h2>
<p>为什么会有路由层？因为在微服务架构设计中，往往并不会直接将服务暴漏给调用端，而是通过调用路由层进行业务隔离，以达到不同的业务调用对应的服务模块。</p>

<p><strong>Spring Cloud Zuul</strong></p>
```

2. 使用Jquery把文章所在容器高度缩小，这样会把内容进行压缩

```js
// 文章所在容器的选择器
var articleSelector = 'article.post.container.need';
// 找到文章所在的容器
var $article = $(articleSelector);

// 文章的实际高度
var article = $article[0], height = article.clientHeight;
// 文章隐藏后的高度
var halfHeight = height * 0.4;
// 隐藏缩小
$article.css('height', halfHeight + 'px');
$article.addClass('lock');
```

3. 给文章加一点朦胧感，渐变隐藏

```css
.asb-post-01 {
 position: absolute;
 left: 0;
 bottom: 0;
 width: 100%;
 display: none;
 z-index: 10000;
margin-bottom: 0;
}

.asb-post-01 .mask {
 height: 240px;
 width: 100%;
 background: -webkit-gradient(linear, 0 top, 0 bottom, from(rgba(255, 255, 255, 0)), to(#fff));
}
```

4. 从UM全局唯一ID中获取token
友盟作为网站数据采集服务，会生成一个针对用户的全局唯一值UM_distinctid，而我们需要就使用这个值部分截取后作为唯一token加锁钥匙

```other
UM_distinctid = 16e9cd64925334-0882eb883c9554-7711b3e-144000-16e9cd6492631c
```

```js
function getCookie(name) {
	var value = "; " + document.cookie;
	var parts = value.split("; " + name + "=");
	if (parts.length == 2)
		return parts.pop().split(";").shift();
}

function getToken() {
    let value = getCookie('UM_distinctid');
    if (!value) {
        return getUUID().toUpperCase();
    }
    return value.substring(value.length - 6).toUpperCase();
}
```

5. 定时轮旋检查是否关注公众号并解锁，可以优化写入全局Jquery值或者记录在cookie，减少轮询检查次数

```js
// 查询后端的结果
var _detect = function() {
	console.info(token);
	$.ajax({
		url : 'https://bugstack.cn/xx/xx/check',
		type: "GET",
		dataType: "text",
		data : {
			token : token
		},
		success : function(data) {
			console.log(data);
			if (data == 'refuse') {
				_lock();
			} else {
				_unlock();
			}
		},
		error : function(data) {
			_unlock();
		}
	})
}

// 定时任务
_detect();
setInterval(function() {
	_detect();
}, 5000);
```

6. 引导用户关注公众号
现在将token值回显到页面，提醒用户关注公众号回复口令解锁全部文章，以此来得到粉丝的关注。效果如下；



### 3.2 后端

1. 本地环境开发需要安装(免费)http://natapp.cn/，做网络穿透便于我们进行测试
2. 服务度三个主要接口；1同名称的get、post请求，分别用于公众号验验、接收用户行为与回复信息。2给博客提供验证是否解锁接口
3. 在微信公众号；开发->基础设置(服务器配置)，修改配置内容并开启服务，此时服务端会收到验证请求信息
4. Java服务度采用领域驱动设计微服务方式开发，DDD的开发模式会更加清晰以及易于后续功能的拓展
5. (提醒)个人微信号，部分接口权限是没有的，同时如果开启开发者功能配置后，自定义菜单和自定义回复都会失效。而自定义菜单又不开放给个人微信号，所以需要再次配置开启，但是不能修改

#### 开发环境
1. jdk 1.8、tomcat8、idea2018、Maven3
2. Spring Boot 2.1.2.RELEASE
3. mysql 5.6
4. natapp 网络穿透

#### 工程代码

>itstack-ark-wx & 领域驱动设计方式设计

```
/* Detailed source-code truncated for AI context efficiency. */
```

>itstack-ark-wx & 建表语句

```sql
CREATE TABLE
    user_auth
    (
        id bigint NOT NULL AUTO_INCREMENT,
        openId VARCHAR(64),
        token VARCHAR(16) NOT NULL,
        uuid VARCHAR(128),
        createTime DATETIME,
        updateTime DATETIME,
        PRIMARY KEY (id, token),
        CONSTRAINT idx_uuid UNIQUE (uuid)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8
```

**讲解部分重点代码块，完整代码下载关注公众号；bugstack虫洞栈 & 回复：itstack-ark-wx**

**interfaces接口层**

>WxPortalController.java & 接收微信公众号验签与行为信息通知

- 微信公众号都是通过服务提供方的一个接口的get/post请求来执行操作的{这样设计真sao但真香}

- get接口主要是验证签名

- post接口会收到；关注、取消关注、用户的回复信息

```
/* Detailed source-code truncated for AI context efficiency. */
```

>BlogController.java & 博客验权接口，用于判断文章是否解锁

- 因为我们这个服务部署在二级域名下，因此需要设置跨域访问
- 由于我们网站是https加密，那么非https是不能被访问，需要下载安装证书到tomcat服务器
- 本接口只返回success和refuse，通过即可解锁

```java
/**
 * 微信公众号：bugstack虫洞栈
 * 纯洁版博客：https://bugstack.cn
 * 沉淀、分享、成长，让自己和他人都能有所收获！
 * Create by 付政委 on @2019
 */
@CrossOrigin("https://bugstack.cn")
@RestController
@RequestMapping("/api")
public class BlogController {

    private Logger logger = LoggerFactory.getLogger(BlogController.class);

    @Autowired
    private UserLockAuthService userLockAuthService;

    @GetMapping(value = "check", produces = "application/json;charset=utf-8")
    public String check(@RequestParam String token) {
        try {
            logger.info("校验博客浏览用户授权状态{}开始", token);
            boolean status = userLockAuthService.checkAuth(token);
            logger.info("校验博客浏览用户授权状态{}完成", token, status);
            return status ? "success" : "refuse";
        } catch (Exception e) {
            logger.error("校验博客浏览用户授权状态{}失败", token, e);
            return "refuse";
        }
    }

}
```

**application应用层**

- 本层主要定义逻辑分层，属于非常薄的一层，在一些复杂设计中会有一些服务编排
  - UserLockAuthService 用户权限验证
  - WxReceiveService 接收用户行为消息
  - WxValidateService 微信公众号验签
 
 
>UserLockAuthService.java & 定义后由领域层实现

```java
public interface UserLockAuthService {

    boolean checkAuth(String token);

}
```
 
**domain领域层**

- 领域层完成了；权限验证、行为消息处理、公众号验签
- 这里最重要的各种行为消息处理，我们设计为决策树工厂模型，定义了逻辑功能和引擎服务，后续只需要按需扩展即可

>logic/LogicFilter.java & 定义逻辑模型，impl中有对应的一组的实现类

```java
public interface LogicFilter {

    String filter(BehaviorMatter request);

}
```

>logic/impl/SubscribeFilter.java & 其中一个实现，关注时行为处理

```java
@Service("subscribe")
public class SubscribeFilter implements LogicFilter {

    private final String content = "您好！\n" +
            "\n" +
            "非常感谢您关注，微信公众号：bugstack虫洞栈  | 也期待您分享给更多小伙伴！\n" +
            "\n" +
            "bugstack虫洞栈，专注于原创技术专题案例，以最易学习编程开发的方式分享技术知识，让萌新、小白、大牛都能有所收获。目前已经完成的专题有；《Netty4.x从入门到实战》、《手写RPC框架》、《用Java实现JVM》、《基于JavaAgent的全链路监控》、《DDD专题案例》，其他更多专题还在排兵布阵中。\n" +
            "\n" +
            "获取专题案例源码回复；netty案例、rpc案例、用Java实现jvm源码、基于JavaAgent的全链路监控案例、DDD落地。\n" +
            "\n" +
            "联系作者：付政委 | monkeycode";

    @Override
    public String filter(BehaviorMatter request) {
        return content;
    }

}
```

>engine/impl/MsgEngineHandle.java & 引擎路由调用

```java
@Service("msgEngineHandle")
public class MsgEngineHandle extends EngineBase {

    @Value("${wx.config.originalid:你的Err默认值}")
    private String originalId;

    @Override
    public String process(BehaviorMatter request) throws Exception {
        LogicFilter router = super.router(request);
        if (null == router) return null;
        String resultStr = router.filter(request);
        if (StringUtils.isBlank(resultStr)) return "";
        //反馈信息[文本]，暂时只有文本后续按需拓展
        MessageTextEntity res = new MessageTextEntity();
        res.setToUserName(request.getOpenId());
        res.setFromUserName(originalId);
        res.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000L));
        res.setMsgType("text");
        res.setContent(resultStr);
        return XmlUtil.beanToXml(res);
    }

}
```

**infrastructure基础层**

- 本层主要提供基础服务能力，包括数据库操作、缓存操作、工具包等
- 如果你的服务中由redis可以在本层来提供
- 在领域驱动设计中数据库不提倡共用，是单独分离，因为此设计中只有用户表还体现的不明显

>repository/UserAuthGrantRepository.java & 数据库实现

```java
@Repository("userAuthGrantRepository")
public class UserAuthGrantRepository implements IUserAuthGrantRepository {

    @Autowired
    private UserAuthDao userAuthDao;

    @Override
    public void grantAuth(String openId, String token) {
        UserAuth userAuthReq = new UserAuth();
        userAuthReq.setOpenId(openId);
        userAuthReq.setToken(token);
        userAuthReq.setUuid(openId + "_" + token);
        userAuthDao.insert(userAuthReq);
    }

    @Override
    public void revokeAuth(String openId) {
        userAuthDao.delete(openId);
    }

}
```

### 3.3 部署

#### 1. 工程打包

1. springboot配置打包部署成可运行war包

	>pom.xml

	```xml
	<packaging>war</packaging>
	```

	>WxApplication.java

	```java
	@SpringBootApplication
	public class WxApplication extends SpringBootServletInitializer {

		@Override
		protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
			return builder.sources(WxApplication.class);
		}

		public static void main(String[] args) {
			SpringApplication.run(WxApplication.class, args);
		}

	}
	```

2. 修改配置application.yml，数据库配置、微信配置

	```java
	server:
	  port: 80

	spring:
	#  datasource:
	#    username: root
	#    password: 123456
	#    url: jdbc:mysql://localhost:3306/itstack-ark-wx?useUnicode=true&characterEncoding=utf8
	#    driver-class-name: com.mysql.jdbc.Driver


	mybatis:
	  mapper-locations: classpath:/mybatis/mapper/*.xml
	  config-location:  classpath:/mybatis/config/mybatis-config.xml

	# 微信公众号配置信息
	# originalid：原始ID
	# appid：个人AppID
	# token：开通接口服务自定义设置
	wx:
	  config:
		originalid: xxxxxxx
		appid: xxxxxxx
		token: xxxxxxx
	```

#### 2. 服务上线

1. 申请云服务器，目前提供方比较多，一般可以和域名选择一个服务商
2. 准备好Linux服务器jdk1.8、tomcat8 
3. 看个人域名访问情况，酌情申请Https，配置RSA
4. 本地安装XShell、Xftp，方便部署和文件传输
5. 准备好个人微信公众号，用于配置服务
   
6. 启动服务
   ```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 3. 功能验证

1. 验证连接；https://bugstack.cn/itstack-demo-ddd/2019/10/16/DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%BA%8C-%E9%A2%86%E5%9F%9F%E5%B1%82%E5%86%B3%E7%AD%96%E8%A7%84%E5%88%99%E6%A0%91%E6%9C%8D%E5%8A%A1%E8%AE%BE%E8%AE%A1.html

2. 引导提示；


3. 文章解锁；


## 4. 综上总结

1. 还是很感激那些前途的探路人，为原创研发贡献力量
2. 我博客；https://bugstack.cn，可以尝试验证或者克隆对应的代码仓库
3. 利用了11月24日周六给自己加个通宵班完成所有代码的开发和服务申请到部署，从最开始拿到想法到最终实现还是经历了很多坎坎坷坷
4. 这里面还有很多可以优化的点以及一些拓展的功能，后续会陆续完善，如果由小伙伴有好的点子欢迎随时交流
5. 源码贡献给所有研发，微信公众号内回复；**itstack-ark-wx**，即可获得一份基于领域驱动设计开发的微信公众号与博客打通工程(Star&Frok)
6. 夜深人静咣咣敲代码我也会怀疑，我是谁，我在哪，我在干什么！哎，这就是；喜欢干一份工作，往往来自于干了一件喜欢的工作

---

### Md Devops 2020 03 28 GithubAndMyBlogAttacked (`docs/md/devops/2020-03-28-GithubAndMyBlogAttacked.md`)

---
layout: post
category: itstack-code-life
title: 20年3月27日，Github被攻击。我的GitPage博客也挂了，紧急修复之路，也教会你搭建 Jekyll 博客！
tagline: by 付政委
tag: [java,itstack-code-life]
excerpt: 万万没想到！`Github` 竟然受到攻击了！还能让我使用了 `GitPage` 的博客瘫痪了！整个网站一下不能访问了，还是有点慌的，毕竟在这之前没有考虑到还能有这事。
lock: need
---

# 20年3月27日，Github被攻击。我的GitPage博客也挂了，紧急修复之路，也教会你搭建 Jekyll 博客！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/ISA7Nmow-boP1yWStGCuBw](https://mp.weixin.qq.com/s/ISA7Nmow-boP1yWStGCuBw)

## 一、前言

万万没想到！`Github` 竟然受到攻击了！还能让我使用了 `GitPage` 的博客瘫痪了！



整个网站一下不能访问了，还是有点慌的，毕竟在这之前没有考虑到还能有这事。但虽然没有一个准备好了的预案，但也还是可以使用自己技术把这事搞定，尽快恢复。为了可以尽快恢复博客的访问，我把网站迁移到了 `码云` 的Gitpage服务，并开启免费一个月使用（挺香）,并迅速搞定配置以及 ```HTTPS```。嗯！迁移过来速度还比之前快了。但是后来发现有些网络环境下竟然不能访问，这又让我感觉不爽了，否则我都快要交钱给 `码云` (一年90元)。到 `码云` 官网群问使用这个搭建博客，百度收录吗？也没有人回应。**如果不收录我没必要用了就，是吧。钱花了，事没办！** 不过也还好有 Gitee，否则网站不能那么快恢复，如果按照下面的方式搞，至少 `24` 小时才能完事。

接下来就是将网站迁移到我自己买的服务器上，虽然过程比较坎坷，但终究还是满足了我的需求。提升了网站速度、体验，也可以让网站被百度爬虫收录。如果也有小伙伴遇到这样问题或者想建博客，可以按照我下面的步骤，进行安装 `Jekyll` 部署博客。

## 二、版本

>Ruby，一种简单快捷的面向对象（面向对象程序设计）脚本语言，在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发，遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。由 Ruby 语言本身还发展出了JRuby（Java平台）、IronRuby（.NET平台）等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby，直至1995年12月才正式公开发布于fj（新闻组）。因为Perl发音与6月诞生石pearl（珍珠）相同，因此Ruby以7月诞生石ruby（红宝石）命名。

| 序号 | 官网 | 描述 |
|:---:|:---|:---|
| 1 | [https://rubyinstaller.org/downloads/](https://rubyinstaller.org/downloads/) | Ruby官网下载 |
| 2 | [https://gems.ruby-china.com/](https://gems.ruby-china.com/)| 完整 RubyGems 镜像```China``` |
| 3 | [http://www.ruby-lang.org/zh_cn/documentation/](http://www.ruby-lang.org/zh_cn/documentation/)| Ruby 编程文档 |
| 4 | [http://jekyllthemes.org/](http://jekyllthemes.org/) | jekyll 模版 |
| 5 | [https://www.jekyll.com.cn/docs/](https://www.jekyll.com.cn/docs/)| 快速入门手册 |

Ruby 的版本比较多，安装方式也分为整体安装和分开安装(Ruby + devkit)，而这些也是最容易出错的地方。有时候安装完了和自己的不博客版本对不上，而导致报错不能编译。目前经过测试此版本**Ruby+Devkit 2.5.7-1 (x64)**比较适合 ```Jekyll``` 博客的编译部署。如果你在官网下载速度较慢，可以添加**公众号**：```bugstack虫洞栈```，回复邮箱。

## 三、安装

**Ruby+Devkit 2.5.7-1**，完整包的安装过程比较简单，但需要注意以下几点；
1. 安装路径不要有空格，中文等特殊符号
2. 安装中的选项内容按照下图执行
3. 安装完后需要更换数据源，这些内容会在下文具体执行总展示

### 1. 双击打开软件(rubyinstaller-devkit-2.5.7-1-x64)



### 2. 设置路径和选项



- 注意！千万不要把路径设置有空格、中文、特殊符号
- 注意！前两个是必选项，第三个可以不选

### 3. 继续执行直到完成

>点击下一步即可，不需要更改配置



>初步安装成功，点击 `Finsh`



**按照到这我们的软件就已经安装完成了，此时你已经可以执行命令查看版本了。**

```java
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\xiaofuge>ruby -v
ruby 2.5.7p206 (2019-10-01 revision 67816) [x64-mingw32]
```

## 四、配置

在安装完成之后还需要执行一系列配置，才能让软件正常工作。并且不注意英文提示的小伙伴，可能你的一个**回车**就把刚安装好的软件卸载了！

### 1. 更换源

>更新 `Gem` 

```java
C:\Users\xiaofuge>gem update --system
Updating rubygems-update
Fetching: rubygems-update-2.7.7.gem (100%)
Successfully installed rubygems-update-2.7.7
...
```

>查看版本

```java
C:\Users\xiaofuge>gem -v
2.7.7
```

>替换源，否则你会下载的很慢

```java
C:\Users\xiaofuge>gem sources --add https://gems.ruby-china.com/ --remove http
s://rubygems.org/
source https://gems.ruby-china.com/ already present in the cache
source https://rubygems.org/ not present in cache
```

>查看新的源

```java
C:\Users\xiaofuge>gem sources -l
*** CURRENT SOURCES ***

https://gems.ruby-china.com
```

### 2. 基础的安装和配置

接下来的步骤就比较简单了，但整体的过程比较耗时，黑窗口会在我们执行命令后下载大约 `600M` 的软件。 




>命令 1



>命令 2



>命令 3



好！当你顺利安装到此后，你的软件就已经安装完成，可以使用了！

## 五、安装Jekyll

```Ruby``` 软件已经安装完成，接下来就是我们的博客的相关内容的安装了。

>检查版本并安装

```java
E:\>gem -v
2.7.7

E:\>gem install jekyll
Fetching: public_suffix-4.0.3.gem (100%)
Successfully installed public_suffix-4.0.3
Fetching: addressable-2.7.0.gem (100%)
Successfully installed addressable-2.7.0
Fetching: colorator-1.1.0.gem (100%)
Successfully installed colorator-1.1.0
...
ass-converter, rb-fsevent, rb-inotify, listen, jekyll-watch, kramdown, kramdown-
parser-gfm, liquid, mercenary, forwardable-extended, pathutil, rouge, safe_yaml,
 unicode-display_width, terminal-table, jekyll after 33 seconds
26 gems installed
```

>查看安装的Jekyll版本

```java
E:\>jekyll -v
jekyll 4.0.0
```

## 六、创建博客

Jekyll 给我们提供了创建博客的命令，你只需要选择好自己文件夹地址，进入执行即可。

### 1. 进入本地站点

```java
C:\Users\xiaofuge>E:

E:\>cd E:\itstack
```

### 2. 创建博客

```java
E:\>jekyll new myblog
Running bundle install in E:/myblog...
  Bundler: Fetching source index from https://rubygems.org/
  Bundler: Resolving dependencies.............
  Bundler: Using public_suffix 4.0.3
  Bundler: Using addressable 2.7.0
  ...
  New jekyll site installed in E:/myblog.
E:\>cd myblog
```

### 3. 编译博客

这里执行的编译是默认本地编译，也就是编译后文中都是 ```localhost:4000``` 地址开头，不要把这回内容传到服务端。

```java
E:\myblog>jekyll build
Configuration file: E:/myblog/_config.yml
            Source: E:/myblog
       Destination: E:/myblog/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
                    done in 1.184 seconds.
 Auto-regeneration: disabled. Use --watch to enable.
```

- 编译好后看到一个 `_site` 的文件夹，这里就是我们的静态博客内容。

### 4. 运行预览

如果在本地我们没编译而是执行运行预览也是可以的，他会自动进行编译。

```java
E:\myblog>jekyll s
Configuration file: E:/myblog/_config.yml
            Source: E:/myblog
       Destination: E:/myblog/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
                    done in 0.847 seconds.
 Auto-regeneration: enabled for 'E:/myblog'
    Server address: http://127.0.0.1:4000/
  Server running... press ctrl-c to stop.
```

- 这里可以指定端口和IP，也可以控制后台运行，具体可以看到 `十、助记指令`

### 5. 运行效果



- 具体如何使用Jekyll编写博客，可以参考官网文档

>博客结构

```java
├── _config.yml
├── _includes
|   ├── footer.html
|   └── header.html
├── _layouts
|   ├── default.html
|   ├── post.html
|   └── page.html
├── _posts
|   └── 2020-03-28-welcome-to-jekyll.markdown
├── _sass
|   ├── _base.scss
|   ├── _layout.scss
|   └── _syntax-highlighting.scss
├── about.md
├── css
|   └── main.scss
├── feed.xml
└── index.html
```

## 七、克隆博客(使用模版)

好！接下来就是我们的**重点**内容了，虽然默认模版也不难看，但终究不是我们的博客。在这里我的目标是将个人博客进行本地编译运行。如果你有喜欢的模版或者是官网，或者是别人个Github，可以下载到自己本地。

### 1. 下载bundler

```java
E:\itstack\gitee.com\fuzhengwei.github.io>gem install bundler
Fetching: bundler-2.1.4.gem (100%)
bundler's executable "bundle" conflicts with D:/Ruby25-x64/bin/bundle
Overwrite the executable? [yN]  n
ERROR:  Error installing bundler:
        "bundle" from bundler conflicts with D:/Ruby25-x64/bin/bundle
```

### 2. 安装环境 

```java
E:\itstack\gitee.com\fuzhengwei.github.io>bundle install
Fetching gem metadata from http://gems.ruby-china.com/..........
Using rake 12.3.0
Fetching concurrent-ruby 1.0.5
Installing concurrent-ruby 1.0.5
Fetching i18n 0.9.1
Installing i18n 0.9.1
Using minitest 5.10.3
Using thread_safe 0.3.6
Fetching tzinfo 1.2.4
Installing tzinfo 1.2.4
Fetching activesupport 4.2.10
...
lockfile (nokogiri (~> 1.6)).
Either installing with `--full-index` or running `bundle update
```

### 3. 更新bundle(按需执行)

```java
E:\itstack\gitee.com\fuzhengwei.github.io>bundle update
Fetching gem metadata from http://gems.ruby-china.com/...........
Fetching gem metadata from http://gems.ruby-china.com/.
Resolving dependencies....
Fetching rake 13.0.1 (was 12.3.0)
...
```
### 4. 编译

```java
bundle exec jekyll build 
```



### 5. 运行

```java
bundle exec jekyll s
```

>http://localhost:4000/



- 可以看到我们已经很顺利的运行并访问了博客，效果还不错。
- 这会虽然是本地运行，所以里面的链接都是 ```http://localhost:4000/``` ，不能用于服务端部署。

## 八、手动发布

如果部署到服务端，那么我们编译后里面的链接地址都肯定以我们的域名开始，例如；```https://bugstack.cn/```。接下来我们开始执行服务端部署的编译和使用。

### 1. 清空和重新构建

```java
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。

C:\Users\fuzhengwei>E:

E:\>cd E:\itstack\gitee.com\fuzhengwei.github.io

E:\itstack\gitee.com\fuzhengwei.github.io>bundle exec jekyll clean
Configuration file: E:/itstack/gitee.com/fuzhengwei.github.io/_config.yml
           Cleaner: Removing ./_site...
           Cleaner: Nothing to do for ./.jekyll-metadata.
           Cleaner: Removing ./.jekyll-cache...
           Cleaner: Nothing to do for .sass-cache.

E:\itstack\gitee.com\fuzhengwei.github.io>bundle exec jekyll build
Configuration file: E:/itstack/gitee.com/fuzhengwei.github.io/_config.yml
            Source: E:/itstack/gitee.com/fuzhengwei.github.io
       Destination: E:/itstack/gitee.com/fuzhengwei.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
   GitHub Metadata: No GitHub API authentication could be found. Some fields may
 be missing or have incorrect data.
                    done in 18.102 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

E:\itstack\gitee.com\fuzhengwei.github.io>
```

- 在以上我们分别执行了清空(```bundle exec jekyll clean```)和构建(```bundle exec jekyll build```)，接下来看以看到文件下的 ```_site``` 内容的生成。

### 2. 部署到远程服务器

远程服务器的部署主要依赖于大家个子使用的服务器类型，我的手里有一台云虚拟机，通过FTP的方式进行部署即可。如下；



- 部署以后我们在线网站就可以访问了；[https://bugstack.cn/](https://bugstack.cn/)

## 九、自动发布

如果每次都是这样去本地编译在部署到服务端，代码又得维护在 `GitHub` 还是比较麻烦的。可以使用；`Github -> Travis CI -> Docker-> VPS`。的方式进行部署，不过还得花点钱买服务器。

- 本地提交博客 Markdown 文件 到 Github 源文件 repository
- Github 触发 Travis CI 执行自动编译
- Travis CI 编译后 push 静态文件到 Github 静态文件 repository
- Travis CI 通知 Docker 重建镜像（预计 5 分钟）
- 服务器休眠 5 分钟后，Travis CI 通知服务器
- 服务器拉取最新镜像，然后停止并删除原容器，用最新镜像重建容器

*这种方式目前我还没有钱和时间去折腾，等后面我的博客访问量和内容更大了以后在投入经历去搞！*

## 十、助记指令

| 序号 | 指令 | 说明 |
|:---:|:---|:---|
| 1 | ruby -v | 查看Ruby版本 |
| 2 | gem update | 更新 |
| 3 | `gem -v` | 查看Gem版本 |
| 4 | gem install jekyll | 安装jekyll |  
| 5 | gem install bundler | 下载bundler |
| 6 | `gem install jekyll-paginate` | 下载jeky-paginate |
| 7 | git clone git@github.com:xiaofuge/xiaofuge.github.io.git | 克隆主题(cd到xiaofuge.github.io，执行jekyll serve 可以在http://localhost:4000看到效果) | 
| 8 | `gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/` | 更换源[https://gems.ruby-china.com](https://gems.ruby-china.com/) |
| 9 | jekyll new myblog | 初始化默认博客 |
| 10 | bundle install | 进入博客文件夹执行初始化| 
| 11 | jekyll build | 本地编译默认所有链接为http://localhost |
| 13 | `jekyll build --source <source> --destination <destination>` | 编译指定的文件夹，同时可以设定到指定的地方|
| 12 | jekyll build --destination | 编译到指定地方 |
| 14 | jekyll build --watch | 编译后好自动监听文件变化 自动编译 |
| 15 | bundle exec jekyll build  | 您只需构建您的站点(而不是在本地提供),然后您可以将生成的文件上传到您的服务器（这将生成与_config.yml中配置变量url的值的规范链接） |
| 16 | jekyll clean | 清空编译_site  |
| 17 | jekyll serve | 本地启动服务 |
| 18 | jekyll serve --host 0.0.0.0 --port 80 | 指定ip和端口启动 |
| 19 | nohup jekyll serve & | 后台运行 |
| 20 | ps -axu | grep jekyll | 运行关闭 |
| 21 | kill -9 [pid] | 杀死进程 |

## 十一、总结

- 通过这次 `GitHub` 挂了，也彻底让我的博客又得花钱维护了。不花点钱是真不行！以前我忍受了；速度、收录、体验，但是突然的一挂，啥都拜拜了。所以只能挂到自己的服务器上，还好价格也不贵！毕竟是一个只能支持 PHP、ASP的虚拟机。
- 从没有那件事情是可以轻轻松松的，在 `天灾人祸` 来临的时候，能帮你抵挡的都是你日积月累的能力。就像；**是时候展示真正的技术了！**
- `Jekyll` 搭建的博客还是蛮好看的，也蛮容易维护的。技术人员还是要有自己的博客，通过不停的折腾从里面不断的获取各个技术点的突破。

---

### Md Devops 2020 04 25 《Netty+JavaFx实战：仿桌面版微信聊天》代码开源+上云部署+视频讲解 (`docs/md/devops/2020-04-25-《Netty+JavaFx实战：仿桌面版微信聊天》代码开源+上云部署+视频讲解.md`)

---
layout: post
category: itstack-demo-netty-3
title: 《Netty+JavaFx实战：仿桌面版微信聊天》代码开源、上云部署、视频讲解，只为让你给点个Star！
tagline: by 付政委
tag: [netty,itstack-demo-netty-3] 
excerpt: https://github.com/fuzhengwei/NaiveChat 代码开源，通过视频讲解每一个服务模块的功能，快速入门后并深入学习实践。好！感谢那些默默支持小傅哥的伙伴们！
---

# 《Netty+JavaFx实战：仿桌面版微信聊天》代码开源、上云部署、视频讲解，只为让你给点个Star！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>视频：[https://mp.weixin.qq.com/s/OmXCY4fTfDpkvjlg5ME0ZA](https://mp.weixin.qq.com/s/OmXCY4fTfDpkvjlg5ME0ZA)

>本项目是作者小傅哥使用```JavaFx```、```Netty4.x```、```SpringBoot```、```Mysql```等技术栈和偏向于DDD领域驱动设计方式，搭建的仿桌面版微信聊天工程实现通信核心功能。如果本项目能为您提供帮助，请给予支持(关注、点赞、分享)！

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=370435867&bvid=BV1BZ4y1W7fC&cid=183186867&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

## 一、前

与 `Netty` 的缘分是从 5.0 版本开始，当时网上资料也不多，就随着学习整理编写了一整套案例。但也就当我全套的案例编写没多久后，`netty5.0`，因最新版本的性能问题，被官网下掉了并主推 `netty4.0` 版本。好吧！就这样有很多小伙伴问我是不是可以写一套 `netty4.0` 的案例，否则现在看着 5.0 的案例写 4.0 的代码实在难受！

**安排**！从19年开始陆续编写 `netty4.0` 案例，从基础篇、中级篇、高级篇以及源码分析共编写了37个章节，基本可以满足所有小白对 `Netty` 的入门。目前也是我博客里非常火专题内容了。[https://bugstack.cn](https://bugstack.cn)

后来越来越多的小伙伴开始加我微信，一起讨论 **Netty** 学习。在讨论的工程中，遇到各种各样的问题，虽然在案例文章中都有所介绍，但是案例终究是引导入门的，并不是一次完整的实践。及时能看懂只言片语，但真的上手还是有一些难度。

为此！在19年结尾，20年的春节里。发起了`《Netty+JavaFX实战：仿桌面版微信聊天项目》`，并将文章和代码全套梳理发布到 [GitChat](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f) 专栏，截止到文章发布共计售出有 **716** 份，虽然不多。但好在没人买后**喷**`小傅哥`！还得到很多小伙伴的认可！`「在此感谢」`

---

整个对这次项目来说，只有专栏文章部分是付费的，源码其实一开始就是开源的。只不过我粉丝少宣传不到而已！

所以这次想通过将这份开源`IM`代码部署到云上验证功能，从而加强实践的能力。同时也为了多宣传一下，`真心感谢每一位分享和点赞的小伙伴`！

好！那么接下来我们开始进行服务上云。

*云市场太多，虽然占了伙伴便宜，要了大厂的一个月免费云服务，但没有让我打广告！*

## 二、代码开源

**开源代码** 关注公众号：[`bugstack虫洞栈`](https://bugstack.cn/assets/images/qrcode.png)，回复*源码下载*。`你会获得一个下载链接列表，打开后里面的第15个「因为我有好多开源代码」`，记得给个`Star`！

这套 `IM` 代码分为了三组模块；UI、客户端、服务端。之所以这样拆分，是为了将UI展示与业务逻辑隔离，使用事件和接口进行驱动，让代码层次更加干净整洁易于扩展和维护。

| 序号 | 工程 | 介绍 |
|:---|:---|:---|
| 1 | itstack-naive-chat-ui | 使用JavaFx开发的UI端，在我们的UI端中提供了；登录框体、聊天框体，同时在聊天框体中有大量的行为交互界面以及接口和事件。最终我的UI端使用Maven打包的方式向外提供Jar包，以此来达到UI界面与业务行为流程分离。 |
| 2 | itstack-naive-chat-client | 客户端是我们的通信核心工程，主要使用Netty4.x作为我们的socket框架来完成通信交互。并且在此工程中负责引入UI的Jar包，完成UI定义的事件(登录验证、搜索添加好友、对话通知、发送信息等等)，以及需要使用我们在服务端工程定义的通信协议来完成信息的交互操作。 |
| 3 | itstack-navie-chat-server | 服务端同样使用Netty4.x作为socket的通信框架，同时在服务端使用Layui作为管理后台的页面，并且我们的服务端采用偏向于DDD领域驱动设计的方式与Netty集合，以此来达到我们的框架结构整洁干净易于扩展。 |
| 4 | itstack.sql | 系统工程数据库表结构以及初始化数据信息，共计6张核心表；用户表、群组表、用户群组关联表、好友表、对话表以及聊天记录表。用户在实际业务开发中可以自行拓展完善，目前库表结构只以核心功能为基础。 |

## 三、功能概述

在这套`IM`中，服务端采用`DDD`领域驱动设计模式进行搭建。将 Netty 的功能交给 `SpringBoot` 进行启停控制，同时在服务端搭建控制台可以非常方便的操作通信系统，进行用户和通信管理。在客户端的建设上采用`UI`分离的方式进行搭建，以保证业务代码与`UI`展示分离，做到非常易于扩展的控制。

另外在功能实现上包括；完美仿照微信桌面版客户端、登录、搜索添加好友、用户通信、群组通信、表情发送等核心功能。如果有对于实际需要使用的功能，可以按照这套系统框架进行扩展。具体功能点如下；



## 四、项目演示

>登陆页面



>聊天页面



>添加好友



>消息提醒



## 五、服务上云

### 1. 选择云提供方

*其实云市场有很多，甚至你什么都不做广告都会打到你们口。*

包括；阿里云、华为云、腾讯云、京东云、等等，按照自己喜好下手。我这里是小伙伴赠送的华为云的免费试用，你那按需选择即可。

### 2. 环境配置

**安装包**

1. jdk-8u231-linux-i586.tar.gz
2. apache-tomcat-8.5.37.tar.gz 

**工具**

1. FTP 工具
    1. Mac：FileZilla
    2. Win：Flxe Ftp
    
2. Linux远程连接工具
    1. Mac：用自带的就可以
    2. Win：Xshell 非常好用

**命令**

1. 解压缩：tar -zxvf
2. 环境变量配置 `vi /etc/profile`
    
  ```java
  #JDK全局环境变量配置
  export JAVA_HOME=/usr/local/java/jdk1.8.0_231
  e.xport CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/
  export PATH=$PATH:$JAVA_HOME/bin
  ```
3. 查找占用端口杀死

 ```java
 fuser -v -n tcp 3389
 kill -s 9 2157
 ```

4. mysql授权

 ```java
 select user, host from mysql.user where user='root';
 GRANT all privileges ON 库名.* TO '数据库用户名'@'授权访问的IP' identified by '数据库用户密码';
 flush privileges;  
 ```

5. tomcat启停和查看日志

 ```java
 ./startup.sh 
 ./shutdown.sh 
 tail -f catalina.out 
 ```

### 3. 服务配置

关于服务配置在最上面的**视频**中进行演示操作，其实主要是将服务端代码部署到云服务中。这里最开始主要遇到了一些权限和端口访问的问题，整体来说还是比较顺畅的。

## 六、项目学习

**学习链接**：[https://chat.itstack.org/](https://chat.itstack.org/) - 代码**开源**，文章付费(自愿支持，交个朋友)

* [开篇词](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
* 第 1 章 - UI开发
    * [1.0：专栏学习简述以及全套源码获取](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.1：PC端微信页面拆分及JavaFx使用](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.2：登陆框体实现(结构定义、输入框和登陆)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.3：登陆框体事件与接口](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.4：聊天框体实现一(整体结构定义、侧边栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.5：聊天框体实现二(对话栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.6：聊天框体实现三(对话聊天框)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.7：聊天框体实现四(好友栏)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.8：聊天框体实现五(好友填充框)](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.9：聊天框体事件定义](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.10：练习篇-聊天表情框体实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [1.11：解答篇-聊天表情框体实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
* 第 2 章 - 架构设计
    * [2.1：服务端架构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [2.2：通信协议包定义](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [2.3：客户端架构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [2.4：数据库表结构设计](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
* 第 3 章 - 功能实现 
    * [3.1：登陆功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.2：搜索和添加好友](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.3：对话通知与应答](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.4：用户与好友通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.5：用户与群组通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.6：断线重连恢复通信](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.7：服务端控制台搭建](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.8：练习篇-聊天表情发送功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)
    * [3.9：解答篇-聊天表情发送功能实现](https://gitbook.cn/gitchat/column/5e5d29ac3fbd2d3f5d05e05f)

## 七、总结

- 整篇内容主要讲解实战项目工程`《Netty+JavaFx实战：仿桌面版微信聊天》`的一个框架结构讲解，和部署到云服务器的过程。也是为了方便大家可以在学习过程中，迅速的入门然后深入学习。
- 源码是开放的按需获取进行改造成自己需要的就好，这部分源码也融合`小傅哥`一些开发经验，对于`架设出良好的系统结构`上，会有一定的提升。可以通过关注**公众号：`bugstack虫洞栈`**，进行获取。
- 编写技术文章的这段时间也遇到了很多号主好友，他们甚至`一直连续输出技术文章`，但是基本也没有什么流量。有时候好多好东西还是需要传播，分享，让多多的`原创和优质的内容`，多呈现在大家面前。比如那个并不简单的男人：`小傅哥`！

---

### Md Devops 2020 05 10 自建云盘存储PDF书籍支持在线预览和下载 (`docs/md/devops/2020-05-10-自建云盘存储PDF书籍支持在线预览和下载.md`)

---
layout: post
category: itstack-demo-any
title: 有技术就能自建云盘，PDF预览，文件下载。速度与激情掌握在自己手里！
tagline: by 小傅哥
tag: [java,itstack-demo-any]
excerpt: 读不在三更五鼓，功只怕一曝十寒！使用基于PHP开发的可道云，搭建自己的在线云网盘，图书上传、预览学习、多人操作。爽歪歪！
lock: need
---

# 有技术就能自建云盘，PDF预览，文件下载。速度与激情掌握在自己手里！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、前言

*本篇文章只介绍如何自建云盘，不剐蹭任何云服务。*

在技术学习的路上经常与同好交流心得，时而分享一些技术的PDF书籍。但也经常发现即使是一些可以开源的书籍，分享出来的链接也常常遇到链接失效问题。

尤其是最近希望把看过的一些不错的技术书籍和伙伴的推荐的一起汇总，并附上简单的书评和推荐指数。分享给新人在学习的过程中多有一些干货的内容。同时在一些需要付费的书籍上，也会引导购买纸质书籍。给创作者一份回报，也让自己可以更加方便的阅读。

但在做这件事的时候，经常遇到分享的链接过一会就失效，同时预览效果也不是很好，不能随开随读。所以就萌生了，构建自己的云盘。

`小傅哥`，那个不是简单的男人，一直比较能折腾！*从折腾中不断的触及到新知识领域！*

---

在折腾之前，我是有一些积累的，比如我有一个终身免费的海外云虚拟机，可用部署PHP、ASP项目。所以经常会在上面做一些实验，确定可用后在考虑付费去购买部署备案。*不得已不谨慎，否则就是成本！*

在这个过程中，我先是考虑PHP有CMS内容管理系统，测试后并不能满足我的需求。接下来就反复更换关键词搜索到了；**可道云** - [`kodcloud.com`](http://www.kodcloud.com/)。这是一款基于PHP开发的私有云存储&协同办公服务，同时可以在本地下载软件管理自建的云盘服务。好，这些我就不多介绍了，可以自行从官网查看。下面先上一张图，让你感受下；



- 初次部署使用后，被这个页面震住了，竟然如此强大。
- 有一个完整的桌面系统，支持企业级使用，可以建立组织关系。`甚至你可以任意调整桌面背景`，功能很好。
- 可以分享文件成链接，支持设置隐私级别，与其他云盘功能一致。且对浏览PDF效果很理想，可以在线阅读。
- 另外，有免费版！免费版就是你不要通过代码去改一些显示内容，否则会提示升级到付费版本。

**好！** 那么接下来，就教你如何去部署这样一款自己的云服务。

## 二、系统环境

1. PHP云虚拟机，也可以部署到本地。php 5.3及以上另外使用 php7.3，开启缓存效果更佳。
2. mysql 5.7，或者sqlite。如果有Redis服务，还可以支持缓存。
3. IDEA，Java开发同学比较喜欢。主要用在FTP功能，非常方便管理。
4. Github代码：[https://github.com/kalcaddle/KodExplorer](https://github.com/kalcaddle/KodExplorer)
5. 官网下载：[https://kodcloud.com/download/](https://kodcloud.com/download/)

## 三、工程部署

*本文中使用了到云虚拟机的方式进行部署，支持PHP的虚拟机一般会自带数据库服务。只需要把代码上传进去后，打开域名即会提示安装，按照步骤执行即可。*

使用IDEA打开下载后的 PHP 云盘工程，如果你安装了PHP版本IDEA开发工具，也可以。

### 1. IDEA 配置FTP和上传代码

在IDEA中有一个非常牛的功能，就是可以配置；FTP、FTPS、SFTP。这样就可以在开发的过程，直接将代码上传到虚拟机云服务中。

#### 1.1 配置路径

`Tools -> Deployment -> Configuration` - 按照路径找到后填写ftp链接信息。



#### 1.2 上传文件

配置好路径后，就可以打开FTP服务。在工程中点击上传文件即可。



### 2. 云盘安装和配置

安装过程非常简单，只要打开我们的云虚拟机配置的域名，进行访问即可。他会提示你按照步骤进行按照，你只需要准备好PHP版本、数据库`用户名`、`密码`即可。

#### 2.1 服务安装

**环境检测**



**数据库设置**



**安装完成**



#### 2.2 初始设置

按照执行步骤安装完成后，现在就可以使用了。整体的页面功能也非常简单易操作。如果你有一些其他需要也可以在**桌面**进行设置。

**名称信息**



**资源上传**



**扩展功能**





**到这**，我们的自己的云盘就已经安装好了，那么接下来就可以进行使用了。😺开心！

## 四、云盘使用「分享书籍」

如果以上书籍有任何涉及网络不可传播，随时删除！



### 1. 上传PDF书籍



- 上传的过程非常简单，还可以批量上传。具体速度取决于你的云服务。

### 2. 设置外链



分享外链可以设置的功能非常多；

- 是否设置提取码
- 标题修改
- 可见用户权限
- 到期时间
- 下载次数和禁止下载

### 3. 分享链接

[`分享一波提升技术格调的书籍19本：`https://github.com/fuzhengwei/CodeGuide/wiki/值得一看的好书](https://github.com/fuzhengwei/CodeGuide/wiki/%E5%80%BC%E5%BE%97%E4%B8%80%E7%9C%8B%E7%9A%84%E5%A5%BD%E4%B9%A6)



## 五、总结

- 技术总是能让生活越来越美好，永远不要局限在自己的小窝里去点评一件你尚未了解清楚的事情。
- 个人建造云盘在号主、学校、社团、小企业中都有一定的用武之地，自行体会建设。可能你不知道的事情总在创造价值。
- 如果你说这是`PHP`的，不要在意语言！所有的技术都是为了产品服务于业务，用于承载多样性用户行为数据的。

---

### Md Devops 2021 01 24 一天建4个，小傅哥教你搭博客！ (`docs/md/devops/2021-01-24-一天建4个，小傅哥教你搭博客！.md`)

---
layout: post
category: itstack-code-life
title: 一天建4个，小傅哥教你搭博客！
tagline: by 小傅哥
tag: [java,itstack-code-life]
excerpt: 最早大家都喜欢倒腾自己的QQ空间，装修的各式各样，可那炫耀。但终究这个QQ空间里面，还有很多东西不能让自己随意摆弄。不知道是不是此类好奇和爱好，让很多人走上了编程开发的道路。
lock: need
---

# 一天建4个，小傅哥教你搭博客！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/ZoQ0xAphJQkP_pb8H08BMg](https://mp.weixin.qq.com/s/ZoQ0xAphJQkP_pb8H08BMg)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video"  src="//player.bilibili.com/player.html?aid=251392079&bvid=BV1ov411u7kK&cid=436913896&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

## 一、前言

`压测了，小傅哥一天能搭4个博客！`

好学、乐学、博学、恒学、会学和用学，学以致用。一起学习成长的很多同好以及我自己，都是同样喜欢折腾的人。

最早大家都喜欢倒腾自己的QQ空间，装修的各式各样，可那炫耀。但终究这个QQ空间里面，还有很多东西不能让自己随意摆弄。不知道是不是此类好奇和爱好，让很多人走上了编程开发的道路。

就折腾博客而言，在大学开始就不停的折腾。从一个网页能被宿舍人访问、被校友访问、被家人看到，那个兴奋劲还是十足的。哪怕是半夜也是一遍遍的折腾写着html，虽然丑了吧唧的！

---

最近有不少粉丝问小傅哥，自己也想搭建个自己的博客系统写写文章，但不知道怎么弄。正好小傅哥也确实折腾过各种博客的搭建，了解一些坑坑洼洼，算是给后面的司机开开路。

**本文主要向大家介绍**：
1. 4类静态博客，hexo、docsify、jekyll、vuepress，的差异和特点
2. 在 GitPage 上部署自己的博客
3. 独立域名+个人服务器，部署博客
4. 另外小傅哥把这些博客脚手架统一放到Github仓库，方便大家使用时候可以更方便。*关注公众号：bugstack虫洞栈，回复：博客系统*

*有了这些参考，大家就可以选择适合自己的博客系统了，开心的写博客。*

## 二、你要准备的东西

- **简单记录**：Github账号或者Gitee账号，使用两家的免费静态网页托管服务即可。
- **绑定域名**：如果你想通过自己的域名访问博客，Github与Gitee都支持配置，但Gitee需要付费。不过Gitee对于国内的访问速度要好一些。
- **访问速度**：当你的博客想被更多人访问并且也在意网页的打开速度和体验，那么就需要一个独立的服务器和域名了。*这个服务器可以部署静态网页即可*

综上，是每一个人建博客的不同目的和需要的内容，按需选择即可。

另外，GitPage配置参考：[https://docsify.js.org/#/zh-cn/deploy](https://docsify.js.org/#/zh-cn/deploy) 在Github的配置中，可以选择根目录和docs两个文件夹，作为静态博客的仓库。所以在选择下面四类博客中，都是把docs文件夹预留出来，方便使用。

## 三、4种博客的搭建



- 小傅哥把四类比较常用的博客，源码部分放到这个集中的仓库，方便大家在使用的时候直接克隆走。
- 关于这四类博客的建设，会在以后陆续的完善内容。如果你感兴趣也可以参与到项目中。
- 下载地址：[https://github.com/BlogGuide](https://github.com/BlogGuide)

### 1. hexo



- **介绍**：Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown（或其他渲染引擎）解析文章，在几秒内，即可利用靓丽的主题生成静态网页。
- **官网**：[https://hexo.bootcss.com](https://hexo.bootcss.com/)
- **案例**：[http://hexo.blog.itedus.cn](http://hexo.blog.itedus.cn/)
- **源码**：[https://github.com/BlogGuide/hexo.blog.github.io](https://github.com/BlogGuide/hexo.blog.github.io) - *克隆到自己的仓库*
- **命令**：
```java
npm install hexo-cli -g
hexo init blog
cd blog
npm install
hexo generate # 生成
hexo server   # 启动服务
```
- **特点**：
  - hexo的主题特别多，选择性很高
  - 需要本地编译后，把编译文件推送到Github
- **其他**：
  - 因为需要编译和推送，如果只是想简单的写博客，不推荐使用。
  - 但如果想把静态博客部署到个人的服务器，那么就非常适合了。


### 2. docsify



- **介绍**：docsify 可以快速帮你生成文档网站。不同于 GitBook、Hexo 的地方是它不会生成静态的 `.html` 文件，所有转换工作都是在运行时。如果你想要开始使用它，只需要创建一个 `index.html` 就可以开始编写文档并直接[部署在 GitHub Pages](https://docsify.js.org/#/zh-cn/deploy)。
- **官网**：[https://docsify.js.org/#/zh-cn](https://docsify.js.org/#/zh-cn/)
- **案例**：[http://docsify.blog.itedus.cn](http://docsify.blog.itedus.cn/)
- **源码**：[https://github.com/BlogGuide/docsify.blog.github.io](https://github.com/BlogGuide/docsify.blog.github.io) - *克隆到自己的仓库*
- **命令**：
```java
npm i docsify-cli -g # 全局快速安装
docsify init ./docs  # 初始化项目
docsify serve docs   # 本地预览
```
- **特点**：非常简单、干净，直接把工程文件和md博客推送到Github即可，不需要本地维护编译。

### 3. jekyll



- **介绍**：一个简单的，基于引导的主题。特别是对于那些喜欢在网站上展示自己的项目并喜欢做笔记的开发人员。还有一些神奇的特征需要发现。
- **官网**：[https://github.com/DONGChuan/Yummy-Jekyll](https://github.com/DONGChuan/Yummy-Jekyll)
- **案例**：[http://jekyll.blog.itedus.cn](http://jekyll.blog.itedus.cn/)
- **源码**：[https://github.com/BlogGuide/jekyll.blog.github.io](https://github.com/BlogGuide/jekyll.blog.github.io) - *克隆到自己的仓库*
- **命令**：
```java
Fork code and clone
Run bower install to install all dependencies in bower.json
Run bundle install to install all dependencies in Gemfile
Update _config.yml with your own settings.
Add posts in /_posts
Commit to your own Username.github.io repository.
Then come back to star this theme!
```
- **特点**：这个博客的主题其实有点重，在写博客的时候需要人工维护的内容较多。但同样这个主题有一个好处就是如果使用Github，那么就直接把项目和博客传到Github即可，不需要本地编译。

### 4. vuepress



- **介绍**：VuePress 由两部分组成：第一部分是一个[极简静态网站生成器 (opens new window)](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/core)，它包含由 Vue 驱动的[主题系统](https://vuepress.vuejs.org/zh/theme/)和[插件 API](https://vuepress.vuejs.org/zh/plugin/)，另一个部分是为书写技术文档而优化的[默认主题](https://vuepress.vuejs.org/zh/theme/default-theme-config.html)，它的诞生初衷是为了支持 Vue 及其子项目的文档需求。
- **官网**：[https://vuepress.vuejs.org/zh](https://vuepress.vuejs.org/zh/)
- **案例**：[http://vuepress.blog.itedus.cn](http://vuepress.blog.itedus.cn/)
- **源码**：[https://github.com/BlogGuide/vuepress.blog.github.io](https://github.com/BlogGuide/vuepress.blog.github.io) - *克隆到自己的仓库*
- **命令**：
```java
npm install vuepress # 安装
vuepress build docs     # 构建，生成html，可以用于部署
vuepress dev docs       # 启动，http://localhost:8080/
```
- **特点**：基于vue实现的博客，功能很多适合扩展。很适合部署到个人独立的服务器，如果是部署到Github，可以参考*源码*，在一个工程中提供docs用于存放生成的网页，这样在Github就不需要再维护额外的分支。

## 四、部署到自己的服务器

- **博客**：vuepress
- **软件**：Idea、ftp[可选]
- **环境**：域名、备案、SSL证书、服务器

vuepress的博客项目放IDEA中打开和日常维护就可以了，而且IDEA只提供了FTP的功能，也可以方便上传服务到远程服务器。

关于域名和服务器等需要购买，另外还需要备案才能正常使用。如果你想域名有一个小锁头的安全提示，则需要ssl证书，一般可以免费获取。

其实小傅哥已经有一个 [bugstack.cn](bugstack.cn) 博客，本次是又申请了一个新的域名 [itedus.cn](itedus.cn) 想着再搭建一个玩玩，折腾！

### 1. IDEA 配置 FTP

在IDEA的菜单栏上，Tools 中有一个 Deployment 的选项，可以配置FTP以及其他SFTP。



- Host：你购买的服务器都会提供FTP功能，在里面有host地址
- User name：用户名
- Password：密码
- 配置完成后，在Deployment打开的菜单选项中，会有一个 `Browse Remote Host` 打开以后可以在IDEA中看到了。

### 2. 上传静态网页



- 到这就可以直接上传了你的静态网页到服务器了
- 其实你还可以基于 Github 的 Webhooks 配置自动推送，但整体配置和实现的内容比较多

## 五、总结

- 与CSDN、掘金、思否、开源中国等提供的博客相比，自己维护的博客开发还是需要一些时间精力和运营成本的。但如果想给自己的知识一个实践的机会，就值得折腾。
- hexo、docsify、jekyll、vuepress，四类博客各有自己的特点，有的需要编译上传，有的直接推送Github即可。但想有自己的域名和整体的体验，就需要购买服务器和备案域名。
- 本篇文章只为送给那些想折腾一下的伙伴提供一些可实现的路径，但这条路径上如果你想真的搭出一个称心如意的博客，要搞的东西还很多。甚至你会像我一样折腾到公众号开发与博客联动等等，好！助力你做个喜欢折腾的人！

---

### Md Devops 2021 04 11 Cloudreve 自建云盘实践，我说了没人能限得了我的容量和速度！ (`docs/md/devops/2021-04-11-Cloudreve 自建云盘实践，我说了没人能限得了我的容量和速度！.md`)

---
layout: post
category: itstack-code-life
title: Cloudreve 自建云盘实践，我说了没人能限得了我的容量和速度！
tagline: by 小傅哥
tag: [java,itstack-code-life]
excerpt: 为啥要用自建网盘，市面上的云盘不香了？就像我作为技术号主想分享一些自己总结的资料，放到一些云盘以后有时候会被其他不知道从哪冒出来的小伙伴给举报，举报链接就取消了，取消了链接也就影响了我的资料分享。
lock: need
---

# Cloudreve 自建云盘实践，我说了没人能限得了我的容量和速度！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w](https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=676376354&bvid=BV1UU4y1u7sR&cid=436918474&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

## 一、前言

`为啥要用自建网盘，市面上的云盘不香了？`

每一个用户需求的背后都是因为有场景存在，而这些差异化的场景也都是因为不同的用户类型产生的。

就像我作为技术号主想分享一些自己总结的资料，放到一些云盘以后有时候会被其他不知道从哪冒出来的小伙伴给举报，举报链接就取消了，取消了链接也就影响了我的资料分享。同时我可能还希望我的分享内容能被记录到下载次数、允许几次下载、下载时是否要做一些引流动作等等。

所以类似这样的特殊场景下就需要自建网盘来维护个人需要的资料，与之类似的还有一些公司或者组织都会建相对私域的网盘功能服务功能，给予内部用户使用。

**所以**，也并不一定市面的网盘不香了，只是因为我有需要自建网盘。在这条路上我尝试过自建、kodexplorer、Owncloud等，恰巧最近发现了 Cloudreve 尝试体验后感觉更香，支持的功能更多。所以准备给小伙伴分享下关于 Cloudreve 的安装、配置和使用，也让有需要的小伙伴可以尝尝鲜。

## 二、Cloudreve 介绍

**Cloudreve**，帮助您以最低的成本快速搭建公私兼备的网盘系统。



### 🔉 功能



### ✨ 特性

- ☁️ 支持本机、从机、七牛、阿里云 OSS、腾讯云 COS、又拍云、OneDrive (包括世纪互联版) 作为存储端
- 📤 上传/下载 支持客户端直传，支持下载限速
- 💾 可对接 Aria2 离线下载
- 📚 在线 压缩/解压缩、多文件打包下载
- 💻 覆盖全部存储策略的 WebDAV 协议支持
- ⚡ 拖拽上传、目录上传、流式上传处理
- 🗃️ 文件拖拽管理
- 👩‍👧‍👦 多用户、用户组
- 🔗 创建文件、目录的分享链接，可设定自动过期
- 👁️‍🗨️ 视频、图像、音频、文本、Office 文档在线预览
- 🎨 自定义配色、黑暗模式、PWA 应用、全站单页应用
- 🚀 All-In-One 打包，开箱即用

### 📌 资料

1. 官网：[https://cloudreve.org](https://cloudreve.org)
2. 文档：[https://docs.cloudreve.org/getting-started/install](https://docs.cloudreve.org/getting-started/install)
3. 社区：[https://forum.cloudreve.org](https://forum.cloudreve.org/)
4. 源码：[https://github.com/cloudreve/Cloudreve](https://github.com/cloudreve/Cloudreve)
5. 演示：[https://demo.cloudreve.org](https://demo.cloudreve.org)

## 三、环境准备



1. 云服务器资源或本地服务器，推荐腾讯云轻量服务器，内含宝塔组件，算是是几个云服务里最简单的：[https://console.cloud.tencent.com/lighthouse/instance/index](https://console.cloud.tencent.com/lighthouse/instance/index)
2. 已备案过的域名，如果不需要域名访问，可以直接使用云服务提供的公网IP
3. Cloudreve安装包：[https://github.com/cloudreve/Cloudreve/releases](https://github.com/cloudreve/Cloudreve/releases)

*本章节的案例是基于腾讯云的，如果你使用的是其他云服务器，找到对应的位置配置即可。这些云服务使用方式基本大同小异，遇到问题可以联系对应的云服务客服，不要联系我哈哈哈😄*

## 四、宝塔配置

宝塔是一个简单好用的Linux/Windows服务器运维管理面板，在宝塔后台页面上可以非常方便的安全软件和配置环境。一般可以在云服务器上安装宝塔，有一些厂商也把宝塔集成到自己的云服务器上了。

### 1. 获取用户名和密码



- 地址：[https://console.cloud.tencent.com/lighthouse/instance/detail?rid=8&id=lhins-90pixwzq&tab=application](https://console.cloud.tencent.com/lighthouse/instance/detail?rid=8&id=lhins-90pixwzq&tab=application)
- 进入服务的应用管理会看到`应用内软件信息：宝塔`，在这里点击**登录**按钮后，会获取到宝塔的登录地址、用户名和密码信息「*这些信息可以后期在宝塔后台修改*」。
   ```java
	* Socket connection established *
    Last login: Sat Apr 10 09:33:50 2021 from 119.29.96.147
    [lighthouse@VM-8-9-centos ~]$ sudo /etc/init.d/bt default
    ==================================================================
    BT-Panel default info!
    ==================================================================
    外网面板地址: http://80.71.255.122:8888/cloudtencent
    内网面板地址: http://10.0.8.9:8888/cloudtencent
    *以下仅为初始默认账户密码，若无法登录请执行bt命令重置账户/密码登录
    username: 3kkjecc3
    password: 3f7d2743018b
    If you cannot access the panel,
    release the following panel port [8888] in the security group
    若无法访问面板，请检查防火墙/安全组是否有放行面板[8888]端口
    ==================================================================
   ```

### 2. 8888 端口授权



- 在获取到面板的用户名和密码后，还不能直接访问，因为你的端口还没有授权开通。
- 这时可以在云服务平台上，点击`防火墙`这个配置，添加 8888 端口。

### 3. 登录宝塔后台

地址：[http://80.71.255.122:8888/cloudtencent](http://80.71.255.122:8888/cloudtencent) - `你需要更换为自己的地址`
说明：在初次进入宝塔时会有一些提示和软件安装，选择自己需要的安装即可。
页面：



## 五、服务安装

在宝塔面板的左侧菜单栏有一个终端菜单，点击进入是一个黑窗口，接下来我们就在这里安装整个服务。

### 1. 在宝塔终端查看服务内核

因为不同云服务下可能是 adm 或者 arm 架构，对应下载的 Cloudreve 也会有所不同 `cloudreve_版本号_操作系统_CPU架构.tar.gz`，所以这里我们需要使用 `arch` 命令查看下服务信息。

```java
Last failed login: Sat Apr 10 11:38:41 CST 2021 from 194.165.16.68 on ssh:notty
There were 8 failed login attempts since the last successful login.
Last login: Sat Apr 10 09:57:33 2021 from 127.0.0.1
[root@VM-8-9-centos ~]# arch
x86_64
```

- x86_64：代表 amd64
- aarch64：代表 arm64

### 2. 下载和安装



确定好我们的云服务架构后，选择对应的 Cloudreve 版本，复制地址。我的是：[https://github.com/cloudreve/Cloudreve/releases/download/3.3.1/cloudreve_3.3.1_linux_amd64.tar.gz](https://github.com/cloudreve/Cloudreve/releases/download/3.3.1/cloudreve_3.3.1_linux_amd64.tar.gz) 

**安装命令**

```java
mkdir /www/wwwroot/cloudreve    # 创建一个新文件夹存放程序
cd /www/wwwroot/cloudreve           # 进入这个文件夹
wget https://github.com/cloudreve/Cloudreve/releases/download/3.3.1/cloudreve_3.3.1_linux_amd64.tar.gz # 下载你复制的链接
tar -zxvf cloudreve_3.3.1_linux_amd64.tar.gz   # 解压获取到的主程序
chmod +x ./cloudreve                         				  # 赋予执行权限
./cloudreve                                 						 # 启动 Cloudreve

# 运行信息截取
[Info]    2021-04-10 10:39:59 初始化数据库连接
[Info]    2021-04-10 10:39:59 开始进行数据库初始化...
[Info]    2021-04-10 10:39:59 初始管理员账号：admin@cloudreve.org
[Info]    2021-04-10 10:39:59 初始管理员密码：U4BfStlm
[Info]    2021-04-10 10:40:00 数据库初始化结束
[Info]    2021-04-10 10:40:00 初始化任务队列，WorkerNum = 10
[Info]    2021-04-10 10:40:00 初始化定时任务...
[Info]    2021-04-10 10:40:00 当前运行模式：Master
[Info]    2021-04-10 10:40:00 开始监听 :5212
```

- wget，替换为你的 Cloudreve 地址
- tar，是对应名称一起替换
- 最后把这些命令复制到你的终端黑窗口，它就开始运行安装了。**安装完成以后你会得到一个初始的用户名和密码，复制粘贴保存起来**

### 3. 开放端口 5212

- Cloudreve 安装完成以后，访问地址为你的服务IP:5212，但此时5212并不能直接访问还需要授权。
  
- 仅在宝塔后台授权还不够，还需要在云服务平台的防火墙进行授权，如下：
  

### 4. 登录服务

- 地址：http://80.71.255.122:5212



- 如果一切顺利现在你就可以使用自己的网盘了，但有一点要知道如果你还需要设置域名，那么这个时候先不要使用，先去设置域名，否则一些图片在IP下上传和在域名下上传，分享是有问题的。

## 六、进程守护

其实在服务安装完成后就已经可以正常使用了，但我们很难保证宝塔面板不被重启或者出现异常时也难免要我们自己再启动云盘服务。那么，就需要一个守护进程来自动重启服务。

在宝塔面板的软件商店中，找到 `Supervisor` 安装。Supervisor是用Python开发的一套通用的进程管理程序，能将一个普通的命令行进程变为后台daemon，并监控进程状态，异常退出时能自动重启。

### 1. Supervisor 配置



- 名称：Cloudreve
- 启动用户：root *默认的*
- 运行目录：/www/wwwroot/cloudreve/
- 启动命令：/www/wwwroot/cloudreve/cloudreve

### 2. Supervisor 启动



- 配置守护进程后，点开宝塔面板右上角的重启，进入后`重启服务`
- 重启后再进入到宝塔面板就会看到守护进程已经在启动了，现在启动这个事就交给了 Supervisor 管理

## 七、配置域名

### 1. 解析域名



- 在配置域名之前，需要在你已经准备好的域名下配置一个A记录解析，这样后面才能配置反向代理。

### 2. 反向代理



- 点击宝塔面板左侧菜单中的`网站`按钮，添加一个站点。站点里的域名就是配置解析域名时的信息，我的是`pan.itedus.cn`
- 配置完站点后就需要给这个站点设置一个反向代理，点击它的设置即可进入。在反向代理中添加并设置目标URL：127.0.0.1:5212
- 最后，如果你的域名已经解析完成，那么现在你就可以通过域名访问你的云盘服务了，还可以上传和分享文件。例如我分享的文件：[http://pan.itedus.cn/s/qofO](http://pan.itedus.cn/s/qofO)


## 八、数据库切换

系统默认的数据库是自带的 SQLite，你可改为 Mysql，如下：



1. 数据库类型，目前支持 sqlite | mysql
Type = mysql
2. 用户名
User = Cloudreve
3. 密码
Password = Cloudreve
4. 数据库地址
Host = 127.0.0.1
5. 数据库名称
Name = Cloudreve
6. 数据表前缀
TablePrefix = cd_

- 切换完记得使用命令的方式进行重启，因为此时它需要重新创建账号和密码
- 如果你没有看见账号和密码，那么可以把创建的数据库删掉，重新来一次

## 九、总结

- 关于 Cloudreve 云盘的安装和使用就演示到这里了，如果你感兴趣也可以自己搭建一个。另外 Cloudreve 可以获取到它的源码，在源码的基础上可以添加一些想要的功能，比如在下载的时候设置为关注某些东西在下载等等。
- 除了 Cloudreve 云盘还可以尝试下有道云，这个云盘直接在简单的服务器上就可以直接安装，也可以自动升级，使用起来会简单一些。
- 无论是云服务还是各类工具，多尝试一些这样的东西，可以给自己增加很多其他知识面的理解。也许弄着弄着，你就不只是一个简单的CRUD开发工程师了，可能还是运维、产品、业务！

---

### Md Devops 2021 06 04 【经验分享】码农使用云服务学习，部环境、开端口、配域名、弄SSL、搭博客！ (`docs/md/devops/2021-06-04-【经验分享】码农使用云服务学习，部环境、开端口、配域名、弄SSL、搭博客！.md`)

---
layout: post
category: itstack-code-life
title: 码农云服务使用学习，部环境、开端口、配域名、弄SSL、搭博客！
tagline: by 小傅哥
tag: [java,itstack-code-life]
excerpt: 没云服务？买一个呀，花点钱嘛，花点，哪怕要呢，要不了多少钱！对于一个在校的学生来说，或者是已经工作了，但从没有了解或者接触过服务器的配置，以及如何把自己的代码运行到服务器上。那么你可以参考下面的教程介绍，按照这样一个入门的指导把自己的代码也部署到服务器上试试。
lock: need
---

# 码农云服务使用学习，部环境、开端口、配域名、弄SSL、搭博客！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/N7kzEhGA2432H0h8wqk1AQ](https://mp.weixin.qq.com/s/N7kzEhGA2432H0h8wqk1AQ)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=930916917&bvid=BV1HK4y1X7Dr&cid=350098938&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

## 一、前言

`给你一台服务器，你能把你写的代码部署到线上吗？`

我们常常会听到这样一句话：“为了让研发只关心业务开发，我们做了某某某！”做了啥呢，做了让你不用关心，`系统搭建`、`技术框架`、`核心组件`、`通用模块`以及上线应用时也只是点点点就可以了，也根本了解不到一台应用服务器是如何，`部署环境`、`开通端口`、`申请域名`、`配置SSL`的。所以呢，大多数人的你变得越来越像车间中单一岗位的工具人，想在公司走到更高的岗位或者出了公司想做点事情，都会成为你的瓶颈！

`一套完整的能力范围，要涵盖哪些方面？`



- 当我们以一个需求的诞生从承接到上线，这个过程中大概会经历的角色包括：业务、运营、产品、数据、研发(UI)、测试和运维，产品运用数据和模型，量化业务提出的需求，该如何迭代实现，满足运营使用完成业务目标，再由UI、前后端研发、测试完成项目的开发和验证以及部署到运维配置的线上环境中。
- 站在程序员的角色上以这一整套流程来看，其实很大一部分研发人员只能在编程开发的范围内互动，从技术角色上离的最近的是测试和上线部署，但如果让研发自己去部署测试环境，搭建线上环境就会非常困难，不是说技术层面有多难，而是这个事情几乎就没有经历过，也没想过要去做一做试试。
- 业务、运营、产品、数据中的模型、算法、量化，可能这一部分里研发人员就更远了，压根就不清楚因为什么场景、提出了什么目的、做了怎么的评估、提出了那些手段以及该如何落地，而到研发这能看到的可能仅仅是等待执行的 PRD，正因为总总是这样，所以才有那句话：“你离开公司可能就什么也干不了了！”

**接下来**，给小伙伴讲讲，我对热爱事情的折腾，不只是技术视野范围的拓宽，也可能让你有些意外收获！

## 二、在服务器上花出去的钱！

`这种事你们可以花点钱嘛,花点,哪怕要呢，要不了多少钱！`



**汤师爷说，花点钱，我听进去了！**

其实我一直从不会吝啬于技术学习上的消费，也不会把时间浪费到非个人能长期成长的其他做兼职的事上。从13年毕业工作开始，因为赚钱少，合租的几个伙伴们也有人会出去找点兼职赚钱，我是属于那种不但没周末去赚钱，还把额外省下的钱都买了域名和服务器，从最早的主机屋到百度开始有BCH云服务，也看过七牛云还用过百度云存储，一路折腾下来服务器上也花费了上万块。



这些钱都买啥了？仅域名就买过一堆，包括：itstack.org、yuyueqianli.com、fuzhengwe.cn、linuxjar.org、iteuds.cn、[bugstack.cn](https://bugstack.cn/)等等，那服务器呢？服务器除了正常消费的，还买终身的！！！

**虽然**，花了不少钱，但也正是因为这些消费和不断的倒腾，让我学会了`域名注册`、`域名备案`、`域名配置(A记录、CNAME记录、TXT)`、`证书申请`、`服务搭建`、`宝塔应用`、`配置环境`、`Linux命令`等等。当你有一条具体要做的事情时，你会以这条路径为指导，不断的搜索相应的资料并实践`造作`！

**造作**，出第一个能看得过去的论坛，拥有稍许的流量！



- 不过后来由于干不过一些流氓似的攻击以及 org 域名备案的影响，最终这个小论坛也挂在了奔走的路上。
- 不过好在网站没白`死`，从这里面还是学到了很多东西，包括：部署、上线，运维，在运维过程中发现的一些流量峰值、缓存处理、防刷处理、防盗链处理、用户注册与QQ关联、改造原有php代码，支持一些功能等等，挂的只是网站，但留下的是技术经验！

## 三、把花出去的钱赚回来了！

`我这钱是怎么赚回来的？`

在我搭建论坛、博客、贴吧似的功能并逐步有些许后，就开始有人联系我能不能给他们做一个这样的网站或者企业门户网站。正好当时还在传统行业的我，也有不少业余时间，每天五点半就能下班，当然有时间搞了。好！说干就干，一顿操作下，2年内接了不少私活，也赚了几万块，算是把服务器、域名的钱都赚回来了，也算没白折腾！

### 1. 企业门户网站(5000元)



- **指数**：⭐⭐⭐⭐
- **背景**：刚上班一年左右，高中同学问我学计算机能帮他们公司做个网站吗，就模仿老罗那个锤子公司的样式就行，5000块钱。
- **结果**：我接了，可能也是初生牛犊不怕虎，人家需要用PHP语言写！我一个学Java的，写了快一年的C#，之后用PHP给人家做一个企业门户网站，该说不说胆子挺大！
- **收获**：项目顺利部署完成，5000块钱如约到手，买了我第一个苹果手机 iPhone 4s，仍然在我身边。



### 2. 卖家具宣传网站(2000元)



- **指数**：⭐⭐⭐
- **背景**：14年年初，亲戚家开了一个制作水族箱的小作坊，也是得知我是学计算的。锣鼓喧天的找到我说做一个宣传他们公司商品的网站*外面找人做太贵了！*。
- **结果**：💰钱咱也不好意思要，只是把服务器和域名等费用的钱要了，不过后来给了我个大红包 2000 元，嘿嘿，手一抖，收了！
- **收获**：得益于我已经接过一个项目，所以PHP开发起来也是很容易，按照他们当时喜欢的样式，做了一个仿照点点网的风格网站布局。这次赚的钱交房租了！

### 3. Netty通信框架(2000元)



- **指数**：⭐⭐⭐
- **背景**：14年左右，开始喜欢搞Netty。可能也是当时网上的资料并不多，很多人因为我写了一整套的Netty案例找到我。也就有了这么一次问我能给写个Netty的通信框架不，2000元。
- **结果**：这也是当时头一次不用PHP，而是用Java语言赚到的钱。对我来说还是蛮简单的，1个5:30下班回家就写完了，第二天就给过去了。
- **收获**：知识真的可以变成钱，尤其是那些稍微有点难度，又搞的人不多的时候。

### 4. 讲课、数据采集(11000元)

除了上面接到的私活，还接到了不少七七八八的小活。
- 本科生设计指导，1000元。来自猪八戒网。
- 研究生加密算法，2000元。一个研究生伙伴跟我一起设计出来的，给我从他们学院申请的费用。
- 在线给一个学生讲课，好像一天是50元，将来快1个月，1000元。
- 一个物流数据综合平台，其实功能不算多，有点像记录外贸订单的，5000元。
- 协助一个自己接项目的老板，写了一周Netty编解码部分代码，对接下位机。2000元。

就这样，七七八八的在那两年，赚了2万多块钱。当然还有一部分小的收入，不足1000的。也有被骗过，比如人家拿到项目了就不给钱了或是拿到截图了「*我没加水印*」，人家够演示的了，也不给钱了。

## 四、搞一台服务器咋用起来？

`接下来，教教你怎么把一个服务器用起来！`

对于一个在校的学校来说，或者是已经工作了，但从没有了解或者接触过服务器的配置，以及如何把自己的代码运行到服务器上。那么你可以参考下面的教程介绍，按照这样一个入门的指导把自己的代码也部署到服务器上试试。

可能还有很多小伙伴都不知道服务器能干嘛，简单来说，这就是不在家里，你的一台虚拟电脑，而且是 24小时运行不宕机的，你可以在上面练习网络编程(有公网IP)、中转服务器，以及如下：

1. 搭博客：https://mp.weixin.qq.com/s/ZoQ0xAphJQkP_pb8H08BMg
2. 搞论坛：phpwind、Discuz、wordpress(有博客和论坛等模板) 
3. 弄网盘：https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w
4. 聊天室：https://mp.weixin.qq.com/s/OmXCY4fTfDpkvjlg5ME0ZA
5. 其他的：练习下自己的项目、搞个集群、玩玩ES、弄弄实战、留着接私活给别人部署演示

而这些内容的练习，都能让你把一整套从研发到运维的内容玩透，彻底的了解域名、备案、ssl、宝塔、Linux常用命令等等。

### 1. 先neng个服务器

首先，无论你是否有服务器，你都可以跟小傅哥一起学习关于服务器的使用，我们建了个群专门学习服务器，添加我的微信：fustack，备注：`服务器学习加群`。

如果你还是一个新用户小白，那么可以跟着我的流程一起来，先neng一个便宜的服务器，学习使用即可。这里小傅哥给新人弄了个活动，79元即可买一台一年有效期的服务器，还是比我以前买的便宜多了！



- 购买链接：[https://dashi.aliyun.com/site/xiaofuge/618](https://dashi.aliyun.com/site/xiaofuge/618) - `不方便复制，也可以直接阅读原文进入`
- 优惠价格：~~¥1,234.20~~ `¥79`
- 参与条件：`¥79` 仅适用于*新注册*或*注册未购买*的用户，如果你是老用户可以找下`对象`或`媳妇`的帐号注册。



- 当你购买服务器的时候会看到，`地域`、`实例`、`操作系统`等，地域北京、上海、杭州的网速比较好，张家口的便宜但是网速会比较慢。操作系统默认即可，停机后可以更换。

### 2. 服务器介绍

在购买完服务器后，等待云平台数分钟初始化服务，完事就可以直接使用配置。如下：



- 重置密码：点击你的实例，蓝色的这个字母，进入后再右侧有一个，`重置实例密码`，操作。
- 远程链接：点击`远程链接`即可链接到你服务上，它是一个在线的操作。你可以通过本地的软件 xshell 链接到服务上去。
- 更换系统：如果你对自己默认选择的系统不是很满意或者有其他需求，都可以点击停止系统，之后开始操作系统更换。

### 3. 系统更换成宝塔镜像

对于服务器系统来说你可以使用Linux命令安装各项服务组件，例如k8s、docker、jdk、tomcat、mysql或者php需要的内容等，但对于实际使用的运维来说，我们更希望运维成本越低越好，所以这里我们选择了[宝塔](https://www.bt.cn/)，这样一个服务器运维面板来管理我们的服务器。

在各类的云平台上，包括：百度云、华为云、阿里云、腾讯云，都可以安装宝塔的，有的云平台还会有自己的已经准备好的宝塔镜像，这里我们以阿里云服务为例，把系统停机更好为宝塔。

**停机**



- 位置：点击云服务的实例，就可以进入到这个页面
- 操作：更换系统之前我们需要先进行停机操作，停机后就可以点击更换操作系统了

**换系统**



**选镜像**



- 更换完系统进行确认订单，接下来会跳转到管理后台，这时稍等会，服务器会进行启动。

### 4. 配置并登录宝塔

**远程登录**





- 这一步我们直接在网页上登录了，你也可以使用 xshell 登录公网IP

**初始化宝塔**

命令：`[root@CodeGuide ~]# bt default`



**配置安全组**





- 宝塔的访问要配置 8888 端口，否则是不能访问到的，这个在服务器的安全组中开放即可。
- 这里我们为了方便就直接开启全部的了，如果你是实际使用，可不能这样操作，否则很不安全！

**登录宝塔**



- 地址：http://39.96.73.xxx:8888/ - `换成你的地址`
- 账号：用户名和密码已经在控制台打印，你可以复制自己的，登录宝塔后可以修改这个默认的密码

### 5. 安装阿帕奇和FTP

接下来我们在宝塔中安装一个阿帕奇服务器和FTP，这样就可以部署和访问我们的静态博客了，也就是一个html，如下:

**安装 Apache**



- 安装过程中会自动的执行一些命令，这个你不用管，只要默默看着就行了。

**安装 FTP**



- 安装 FTP 主要是为了通过本地可以把文件传送到服务器上，比如你的一个静态博客是 html，就可以通过 FTP 传到服务器上。

### 6. 网站配置

安装了阿帕奇和FTP我们就可以简单的配置一个站点了，有了这个站点就可以访问到我们自己的博客！

**创建站点**



- 创建站点的适合如果你还没有申请域名，或者域名还没有备案呢，那么就可以直接把公网IP填写进来。

**访问站点**



- 地址：http://39.96.73.167/　在访问的时候，你换成自己的ＩＰ即可

### 7. 网站内容



- 在宝塔的文件里，你可以选择第6步骤中添加的站点，在里面找到你的文件，做一些修改动作。这个时候在访问网站，就会发现内容已经是你新的内容了。

### 8. 域名配置

如果你有域名并已经备案好了，那么在创建站点的时候就可以直接把域名配置上，在访问你的网站的时候就可以通过域名访问了。



- 添加域名：这个里面小傅哥配置的是已经申请好并备案了的域名，你配置成你的就可以。记得配置好域名后，需要在你的域名服务里，通过A记录把服务器IP映射配置上去。
- FTP 配置：为了更加方便的上传你的文件，你可以把FTP打开，这样就可以通过FTP传输配置了。
- 访问地址：[http://blog.itedus.cn](http://blog.itedus.cn/) - `由于域名不是在阿里云，可能http会监测为未备案，拒绝访问`

### 9. SSL 配置

关于 SSL 的申请可以有很多免费网站提供，也可以在宝塔中申请，如果你是用阿里云服务，可以免费申请20个 SSL 证书，另外如果你的域名和服务都是在阿里云，那么在申请 SSL 可以直接走 DNS 认证，否则你需要把 DNS 信息手动配置到你自己的域名上去。*放心这个在申请的时候都有提示，按照说明配置即可*



**下载证书**

因为我们需要把 ssl 配置到宝塔上，所以这里需要把 SSL 下载下来，选择 Apache 格式下载。



**配置证书**





- 配置后点击保存即可，另外需要强制开启 HTTPS，否则你的网站访问 http 也能继续访问，就没有意义了。
- 现在你就可以通过 https，访问自己的博客或者网站了，是不看上去高大上了不少！

### 10. 其他说明

可能你还希望配置 jdk、tomcat，没关系，在宝塔里你都可以安装，也可以安装 mysql，有了这些入门的内容，剩下的就可以搜索一些通用配置的内容，也可以在阿里云中搜索。

## 五、总结

- 本文主要介绍了关于一些技术成长有哪些知识点和内容可以扩充你的知识面，以及关于运维服务器的一些操作知识的入门学习。有了这样一个基础的操作领你进门，接下来就可以扩展的搜索很多其他的内容，来完善你要做的一些部署了。
- 另外本文没有介绍域名的注册和备案，这些内容还是很容易的，你只需要在云平台搜索域名或者百度搜索域名注册，都可以找到一个注册的入口。一般.cn的域名是比较便宜的，其他很多域名续费比较贵，另外像.org这样是不能备案的，所以不要选择太格鲁的域名。
- 像是这样的知识一定是动手操作起来才能学到东西，可能在这个过程中你会遇到各种各样的问题，没关系，这些问题都是可以搜到的。
- 另外可以加入我们的服务器学习群，添加我的微信：`fustack`，备注`服务器学习`，群里给大家录制一些操作小视频在群里。也有很多伙伴建好了自己的博客，互相交流学习！
- **重点**：*点击阅读原文，可以购买比较便宜的服务器，用于学习使用，加群还可以有返现*

---

### Md Devops 2021 11 01 迁移Vuepress博客踩坑经历 (`docs/md/devops/2021-11-01-迁移vuepress博客踩坑经历.md`)

---
title: 迁移vuepress博客的踩坑经历！
lock: need
---

# 迁移vuepress博客的踩坑经历！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/B4kDL_ft5Ril2wvjg1odMA](https://mp.weixin.qq.com/s/B4kDL_ft5Ril2wvjg1odMA)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、我，多能折腾！

`🚌 我跟你说，折腾蓄蓝，还能赚钱！`

- 2013年，毕业以学Java的身份进入传统企业写C#和PLC，每天5:30下班，总有伙伴找到我帮忙做个网站。*PS：要用PHP写，省服务器费用！*
- 2014年，租住门脸，下班回来顺便，卖电话、内存卡、充电线、手机壳、充话费
- 2015年，搭建 itstack.org 域名博客，编写 Netty 5.0 案例，后因 org 域名不能备案，博客也挂了
- 2016年，从传统行业进入互联网已经半年，开始疯狂折腾 Java 以前不熟悉的技术
- 2017年，好奇所接触的一切新鲜框架技术，羡慕技术大佬的能力，书童一样学习高并发场景实现，这么大的调用体量怎么没有挂
- 2018年，不只是看了，开始对源码动手，把 RPC 实现了一遍，做了一套监控系统，写了一堆的中间件，申请了好几个专利，差点被淘宝中间件团队挖去。
- 2019年，从《用Java实现一个JVM》开始，捡回我的热情，申请并备案域名、搭建 jekyll 博客、开通公众号，年底成为 CSDN 博客专家并已积累公众号粉丝1k
- 2020年，2月编写第一个基于 Netty 实现的仿微信 IM，放到腾讯技术社区参赛，获得第一名`(运营小姐姐告诉我，她把仿微信IM推给了小马哥，哈哈哈)`。同年`字节码编程`、`设计模式`、`面经手册`等PDF相继出炉，火了 *他们都问我是不是字节的*！
- 2021年，赶在图书节，我的第一本技术书籍《重学Java设计模式》出版了，出书并不是终点，只是想走走没走过的路、爬爬没爬过的山，看看风雨过后的彩虹是否那么绚烂。

**结束了吗？** 不，折腾依旧在！

2021年的1024，小傅哥一路趟坑，把300篇文章的bugstack虫洞栈博客从 jekyll 升级到 vuepress！

这些年的折腾在`域名申请到备案`、`服务器选择到上线`、`PHP开发扩展功能`，`迁移兼容博客`等，经验和技能储备都没问题，也会点 html、css、js、jquery 做自定义的开发处理。但在面对没接触过的 vue 时，依旧有点不知道从哪下手，而为了vuepress博客从能用到好用，*一顿操作差点干拉胯*！

`技术拓宽`、`实力增强`、`薪资拉升`，来吧，**一起折腾**！

## 二、坑，差点肝拉？

可能你没自己搞过 vuepress 的博客，你不知道。它这个[官网](https://vuepress.vuejs.org/zh/)说啥？说：`像数 1, 2, 3 一样容` tui！糟老头子坏的很，没有一点前端知识根本跑不起来，更别说是生产使用，只能算是玩具级别。*当然，不要误会，人家这个也是想着你有vue的知识背景的，不过我不是没有吗！* 为此在我折腾完把坑趟平以后，知道怎么正确操作后，还专门录了个搭建 vuepress 博客教程的视频，如下：

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=251392079&bvid=BV1ov411u7kK&cid=436913896&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

嘿，好嘛！有了这个案例后，我就一直在琢嘛，怎么把我的博客迁移过来呢，毕竟这套架构可以更好的承载我的文章，也能很大程度的提升阅读体验和对博客的操作空间。

日日思念惦记呀，就跟你处对象一样，朝为日，暮为月，卿为朝朝暮暮啊！咋整，办它吧，想过会遇到坑，也提前铺平垫稳了，但无奈还是会有很多因为没折腾过，vue 知识储备不足而遇到的问题。

### 1. 300篇文章迁移，链接问题



- **背景**：旧版博客到新版博客的迁移，不只是想把界面结构更换了，还希望解决文章分类的问题，所以在有些文章会重新摆放它所属的文件夹。
- **问题**：那么就会出现文章路径与原来文章路径不一致的问题。这其中还包括原有文章中用到的图片路径问题。
- **方案**：分两阶段解决，如果目前把旧版文章全部下线会导致很大一部分老用户，尤其是保留了旧版链接的用户，在访问文章时就会出现 404 找不到了文章了，体验非常不好。所以这里上新版博客的同时也保留旧版博客在同一个服务器中，另外把服务器的 404 配置页面配置到 [https://bugstack.cn](https://bugstack.cn) 以免将来旧版链接几乎已经没有什么流量删除时，再次出现 404 所以为了安全起见先把 404 页面配置成首页，这样也能满足用户找到现有的文章路径。

### 2. 浏览器限制cookie，解锁问题



- **背景**：小傅哥的博客有一个`阅读解锁`功能，这个解锁是基于公众号做的开发，浏览器生成通过友盟cookie获取6位的唯一码，当做用户的个人ID，再通过这个ID到公众号输入后绑定到公众号个人身份ID上，就解锁了。
- **问题**：但有些用户限制了浏览器cookie，或者安装了一些拦截广告的插件，那么 cookie 就不能正确拿到了，一点阅读全文这个解锁码就不唯一了，卡卡的闪。我头都大了！
- **方案**：咋办，总不能告诉每个用户，你把插件给我删了 cookie 给我打开吧，那他们肯定觉得傅哥技术拉胯呀！后来我就想肯定会有一个技术手段能在浏览器计算出唯一ID，否则我不登录时候浏览器xxxx，怎么就给我推荐了呢。经过搜索还真有对应的东西，就是浏览器指纹，fingerprintjs 浏览器指纹库，这个库用于查询浏览器属性并从中计算散列的访问者标识符。与 cookie 和本地存储不同，指纹在匿名/私有模式下保持不变，甚至在清除浏览器数据时也保持不变。妥，有了这个技术就妥嘞，在 cookie 限制的情况下，通过浏览器指纹获取唯一ID截取成文章解锁码。

### 3. 构建文件哈希命名，版本问题



- **背景**：看到这的时候我人都傻了，vue 变异出来的文件竟然 `数字+哈希值.js` 想想也对，人家这样可以更好的保证版本升级，不至于出现缓存问题。
- **问题**：有啥问题呢，你看左侧本地和右侧服务器，发现没。只要每次部署一个版本，服务器端就多出一个新的js文件，好家伙这用不了多久，不把我这小服务器干满了吗！！！删除？删错了呢，那多吓人！
- **方案**：其实有时候遇到这样问题不知道咋查你懂吧，搜了半天不如问前端一下，原来这个是可以通过webpack把打包文件名称处理的，也就是你可以让每次的构建出来的 js、css、img 文件名，都是一个固定的名字。但还有点小问题，vue 里是这么搞，vuepress 怎么搞呢，找了不少资料终于找到 chainWebpack 可以配置文件名 `config.output.filename('assets/js/cg-[name].js?v=' + dateTime).end();`

**模块打包配置：**

```java
chainWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
        const dateTime = new Date().getTime();
        
        // 清除js版本号
        config.output.filename('assets/js/cg-[name].js?v=' + dateTime).end();
        config.output.chunkFilename('assets/js/cg-[name].js?v=' + dateTime).end();
        
        // 清除css版本号
        config.plugin('mini-css-extract-plugin').use(require('mini-css-extract-plugin'), [{
            filename: 'assets/css/[name].css?v=' + dateTime,
            chunkFilename: 'assets/css/[name].css?v=' + dateTime
        }]).end();
    }
}
```



- 通过这样配置后，再打包出来的文件就都是 `cg-名称.js` 的文件了，每次 push 到我的站点服务器是上就可以只有一份同名的 js 了，不至于把我服务器搞爆。

### 4. Java VS PHP 公众号开发，服务器资源问题

**流程图**



**DDD + PHP = 爷青回**



- **背景**：因为要开发博客到公众号的引流，所以需要对公众号做一些开发处理。
- **问题**：最初我是使用 Java 语言写了一版，但目前随着用户体量的上升，调用我这个跑着 Java 程序的小服务器，已经有点小马拉大车了。*现象就是服务崩溃，需要重启！！！*
- **方案**：咋办，花钱升级服务器？我有技术我花那钱，闹呢？上PHP呀，这玩意多升服务器资源，况且我在13年就折腾会了，把DDD思想给我架到PHP上，让它爷青回！

## 三、那，还能干啥？

`你觉得视野范围重要吗，如果我不曾如此折腾，可能与我相遇的美好，也都将错过！`

哪怕是工作，我也不希望自己是一个工具人。趁年轻、趁着有资源、趁着有时间，多给自己补充一些未来的可能，你现在所学到的所有知识、所结交的所有人脉、所开拓的所有技能，都将会在未来使用上，这些一点一点的点，会聚合成一条条知识线，在撑起你整个人生的页面。

尤其是现在在大厂，可能很多时候自己接触的工作范围是非常局限的，只是知道自己把代码写好了就可以了，关于它是怎么跑起来的，部署到哪里了，域名、VIP、Nginx、CDN、SSL，也并不清楚都是什么。这会有什么问题吗，短时间不会有，甚至还会做的很开心，但时间长了需要你承担更大的职责了呢，又或者需要你自己出去干点啥了呢，怎么在冷启动阶段让自己把这些事拿捏呢？*千万别把补充自己的知识当做卷的借口，否则坑的是自己！*

其实有一台服务器可以做很多事情，这不像你自己开虚拟机，一个模拟环境和真实环境，还是有很大区别的！

你可以用一台服务器部署你在工作中遇到的知识，也可以是自己想学习搭建的系统，就像小傅哥折腾的这些内容：

1. 搭博客：[https://mp.weixin.qq.com/s/ZoQ0xAphJQkP_pb8H08BMg](https://mp.weixin.qq.com/s/ZoQ0xAphJQkP_pb8H08BMg)
2. 搞论坛：phpwind、Discuz、wordpress(有博客和论坛等模板)
3. 弄网盘：[https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w](https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w)
4. 聊天室：[https://mp.weixin.qq.com/s/OmXCY4fTfDpkvjlg5ME0ZA](https://mp.weixin.qq.com/s/gzUrFexHcyCrw7XZ_L7N7w)
5. 其他的：练习下自己的项目、搞个集群、玩玩ES、弄弄实战、留着接私活给别人部署演示

而这些内容的练习，都能让你把一整套从研发到运维的内容玩透，彻底的了解域名、备案、ssl、宝塔、Linux常用命令等等。

---

购买链接：[https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=11388&recordId=1033318&userCode=is4kfbdt](https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=11388&recordId=1033318&userCode=is4kfbdt)
优惠价格：[~~¥1,234.20~~] ¥69
参与条件：¥69 *仅适用于新注册或注册未购买的用户，如果你是老用户可以找下对象或媳妇的帐号注册。*

## 四、嗯，总结一下

- 讲道理，我希望你遇到我，因为总有一些热情于技术的男人，会带着你搞点啥，搞着搞着你的薪资就上去了！
- 做技术号主的两年多，我把自己定位成37开，70%开源贡献社区，沉淀、分享，帮助有需要的技术同号。30%做付费内容用于支撑起可以继续完成70%的事情！
- 我见过自己的粉丝伙伴应届生拿到总包50的，也见过清北出国的，也有高考失利又不断学习考证拿下研究生学位进入大厂管培职位的。但无一例外，这些人从不会给自己设限，甚至是非常自律，很难看到这样的伙伴会去胡扯、瞎聊、当别人的分母，而是不断的“折腾”，折腾学习、折腾感兴趣的事情、折腾自己的爱好，而高薪职位也只不过是过路的风景。
- 趁着年轻：承遇朝霞、年少正恰，整装戎马、刻印风华！

---

### Md Devops 2021 11 07 关于怎么使用 Webhooks 自动部署博客，详细教程文档！ (`docs/md/devops/2021-11-07-关于怎么使用 webhooks 自动部署博客，详细教程文档！.md`)

---
title: 关于怎么使用 webhooks 自动部署博客，详细教程文档！
lock: need
---

# 关于怎么使用 webhooks 自动部署博客，详细教程文档！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)
<br/>原文：[https://mp.weixin.qq.com/s/VtTHUfyiITNSoGy052jkXQ](https://mp.weixin.qq.com/s/VtTHUfyiITNSoGy052jkXQ)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=721628967&bvid=BV11S4y1d7hS&cid=440147596&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

## 一、前言

`小傅哥，我搞了三台服务器，维护学校游戏社站点，我麻了！`

📧**女粉来信**：傅哥，我大二了，就编程学的还可以的那种大二女生😄。最近我不是天天看见一大堆人宣传服务器白皮袄吗，我就在11.1日也买了，还让宿舍的两个同学一起跟着买了，都买了三年。想着这样我们三个人就可以搭建和维护我们学校游戏社团的站点了，日常维护着学校的游戏比赛、宣传、通知，还能顺便就把我学的编程技术用上，一举多得嘛。本来还想，可以赶在 EDG VS DK 的时候上线秀一下呢，但是域名要备案好多天，只能鸽了。而且随着我们三个熬夜的折腾服务器、做站点网站、备案域名，真是遇到太多问题了，以前感觉课本学了就能起飞呢，现在全拉胯了。只能一遍学习傅哥的云服务器操作视频，一遍部署验证，真的学到了好多好多！再次感谢傅哥！那么现在问题来了，就是傅哥你的B站视频只有6节，我看完也跟着做了，但这回我遇到了新的问题，就是就是，我三个服务器，按照视频配置完 Nginx 负载以后，每次都要通过 FTP 把网站文件传到三个服务器上去，有时候还忘记一个。这咋弄呀，傅哥给想想办法嘛。

📨**傅哥回信**：办法是有的，可以把你的网站代码设置私有仓库传到 Github 或者 Gitee，这两个代码库都支持 webhook 简单说就是当你把代码 push 到代码库以后，代码库会调用你预先配置好的一个或者多个回调钩子，其实也就是调用你三个负载均衡的站点提供的 URL，来通知你现在这个代码库有最新更新的代码，你可以在收到 URL 的调用通知以后，通过 `git pull` 命令把最新上传的网站代码，拉取到服务器上。那么现在的效果就是，你把代码维护在 GitHub 以后，上传最新的网站内容以后，三个站点就可以自动部署了，简要流程如下：



**方案流程**：
1. 在自己的网站站点中，提供 webhooks URL 访问地址，配置到 `Github/Gitee` 代码库的 Settings -> Webhooks `在下文中会有详细介绍`
2. 例如图中 webhooks.php 开发的内容就是在接收到调用的时候，获取入参以后开始执行 git pull 操作 `shell_exec("git pull origin main 2>&1");` 
3. webhooks 配置完成以后，当我们再通过 git push 把本地代码推送到仓库(Github/Gitee)的时候，仓库就会调用全部的 webhooks.php，把仓库(Github/Gitee)中的代码拉取到站点中，这样就完成了整个站点内容的更新。

🤔 傅哥，你说的我悟了，但需要你再手把手，操作下！

## 二、环境说明

1. 【必须】使用 [Github](https://github.com/fuzhengwei/CodeGuide)、[Gitee](https://gitee.com/fustack/CodeGuide)、[Codechina](https://codechina.csdn.net/) 维护网站代码，因为这些代码库可以支持配置 webhooks
2. 【必须】Linux 云服务器(公网IP)；安装Git、安装Nginx、安装PHP、安装FTP
3. 【可选】使用宝塔运维面板，部署站点博客，操作起来会比较方便

## 三、站点配置

**首先**，我们使用 Linux 宝塔运维面板，添加一个博客站点，在添加之前需要在宝塔中安装 Nginx、FTP、PHP模块，如果你对这里的操作比较陌生，可以先看小傅哥在B站录制好的云服务器学习视频，地址：[https://space.bilibili.com/15637440/channel/seriesdetail?sid=479958](https://space.bilibili.com/15637440/channel/seriesdetail?sid=479958) `PS：当然你也可以不使用宝塔，通过命令安装 Nginx 或者 Apache 服务器等所需要的软件也是可以的。`

### 1. 环境安装

**安装 Git**

- 需求：在站点接收到 webhooks 回调时，使用 git pull 拉取网站代码，所以需要安装 git
- 命令：`yum -y install git`
- 验证：

```java
[root@CodeGuide ~]# git version
git version 2.27.0
```

**安装 Nginx、FTP**

- 需求：部署博客站点时会需要到Nginx服务器、FTP上传
- 操作：可以直接在宝塔中使用`软件商店`进行安装

**配置 PHP，允许 exec 脚本指令**

- 需求：由于我们使用的是 PHP 开发的 webhook 回调操作，所以这里需要安装 PHP 模块
- 安装：直接在宝塔的软件商店中进行安装即可
- 配置：安装完 PHP 模块以后，还需要对 PHP 的 `php.ini` 进行更改，删除 disable_functions 下的 exec、shell_exec，这样才能在 webhooks.php 文件中，执行脚本命令。如图：

	

### 2. 站点配置



- 环境安装完毕后，就可以添加一个网站的站点了，你的网站运行代码都需要上传到这个站点中，它提供了 FTP 操作以及宝塔运维面板中还有一个`文件`，可以在线修改站点内容。

### 3. 访问站点



- 地址：[http://39.96.73.167](http://39.96.73.167) - 你换成自己的访问IP即可
- 描述：默认创建完站点，会在 `/www/wwwroot/39.96.73.167` 目录下有一个 index.html 此时你可以进行在线修改

## 四、创建公钥

SSH 是 Linux 系统的登录工具，现在广泛用于服务器登录和各种加密通信。

### 1. 查看运行用户

一般php运行使用的是 `www` 用户，我们可以通过 ftp 上传一个 index.php 到站点根目录下，之后进行访问站点，查看项目路径和用户目录。

**index.php 中的代码如下**

```java
<?php
header('Content-type: text/html; charset=utf-8');
ini_set("error_reporting", "E_ALL & ~E_NOTICE");

echo "Hi，Webhooks！By 小傅哥<br/>";

echo '<br/>测试：输出项目路径和用户目录：<br/>';

exec("cd ~ && cd - && cd -", $output);

echo '<pre>';
echo print_r($output);
echo '</pre>';
```

- 如果你未对 `php.ini` 中的 `disable_functions = {exec、shell_exec}` 删掉，那么执行这个 php 文件的中脚本指令会报错。

**访问站点**



- 项目路径：`[0] => /www/wwwroot/39.96.73.167`
- 用户目录：`[1] => /home/www` - *www 就是这个用户目录，也就是我们需要为其创建 ssh 公钥的用户*

### 2. 生成和配置公钥

#### 2.1 开启 www 用户

- 命令：`vim /etc/passwd`
- 配置：把 `sbin/nologin` 为 `bin/bash`
	
	
	
#### 2.2 生成公钥

因为我们已经开始了 www 登录权限，那么在生成公钥之前，需要切换到 www 账户下，命令：`su www`

- 切换用户：`su www`
- 生成公钥：`ssh-keygen -t rsa -C "184172133@qq.com"` - 默认回车即可
- 查看公钥：`cat ~/.ssh/id_rsa.pub` - 其他账户下不可见，只有切换到 www 可见
	
	

#### 2.3 配置公钥(Github)

- 地址：https://github.com/settings/ssh/new
- 配置：把你通过 `cat ~/.ssh/id_rsa.pub` 查看到的公钥，配置到这里即可，如下：

	
	
	- 有了这个公钥的配置，我们通过 webhooks.php 中的脚本指令就可以自动的拉取代码了。

## 五、webhooks 更新博客

### 1. 克隆我的代码



- 源码：[关注公众号：bugstack虫洞栈](#) - 回复：`guide-webhooks` 即可获得 
- 使用：你可以把我的源码先fork到自己的Github，然后部署到你的站点中。在学习完成搞清楚原理后，再处理你自己的站点

### 2. 部署到站点



- 这里我们需要先在站点使用 `git clone ”你的网站代码git地址“`，把Github代码克隆到自己的博客中，其实也就是启动了部署做的作用。而这步操作，其实就是日常使用 Git 的方式，先克隆代码，在不断 git pull 更新。
- 命令：`[www@CodeGuide 39.96.73.167]$ git clone git@github.com:fuzhengwei/guide-webhooks.git` - 注意，你需要切换为自己的代码库地址，否则 webhooks 不能生效

### 3. 更改网站运行目录



- 因为我们已经在博客站点中，从 Github 克隆下来我们的博客运行代码，那么这里需要把网站的运行目录切换到这个文件夹下，这样就能正常访问到我们的博客代码了。

### 4. 配置 webhooks

**webhooks.php**



**回调脚本**

```php
<?php
/**
 * Git webhooks 自动部署脚本
 * 地址：https://github.com/fuzhengwei/guide-webhooks/settings/hooks
 */

// 接收post参数
$requestBody = file_get_contents("php://input");
if (empty($requestBody)) {
    exit('data null！');
}

// Content type = application/json
$content = json_decode($requestBody, true);

// 验证 Webhooks 配置的 Secret，也可以不验证
/*if (empty($content['password']) || $content['password'] != '123456') {
	exit('password error');
}*/

// 项目存放物理路径，也就是站点的访问地址
$path = "/www/wwwroot/39.96.73.167/guide-webhooks/";

// 判断需要下拉的分支上是否有提交，我们这里的分支名称为 main
if ($content['ref'] == 'refs/heads/main') {

    // 执行脚本 git pull，拉取分支最新代码
    $res = shell_exec("cd {$path} && git pull origin main 2>&1"); // 当前为www用户

    // 记录日志 ($content 返回的是一整个对象，可以按需获取里面的内容，写入日志)
    $res_log = '------------------------->' . PHP_EOL;
    $res_log .= '用户 ' . $content['pusher']['name'] . ' 于 ' . date('Y-m-d H:i:s') . ' 向项目【' . $content['repository']['name'] . '】分支【' . $content['ref'] . '】PUSH ' . $content['commits'][0]['message'] . PHP_EOL;
    $res_log .= $res . PHP_EOL;

    // 追加方式，写入日志文件
    file_put_contents("git_webhook_log.txt", $res_log, FILE_APPEND);
}
echo 'done';
```

- 在我们从 Github 克隆下来的代码文件中，有一个名为 `webhooks.php` 的文件，它是用于处理 Github 回调时拉取 Github 对应博客代码库的脚本文件。
- 现在 http://39.96.73.167/webhooks.php 就可以配置到 Github 的 webhooks 下了，如图：
  
  

	- 配置，URL、Content type、Secret、trigger，配置完成后确认即可，另外你可以把多个服务器实例都配置上 webhooks，这样就可以在推送代码到 Github 仓库时一起部署了。

## 六、部署验证

**目前**，访问博客是这样，如下：`接下来我们开始修改博客文件并提交，验证自动部署更新站点`



### 1. index.php 新增代码



- 你可以在 index.php 文件中修改任意内容，或者添加新的内容。

### 2. push 代码到 Github



- 推送新修改的内容，到代码库中，等待 Github webhooks 回调脚本

### 3. 验证博客更新

- 地址：[http://39.96.73.167/](http://39.96.73.167/)
- 效果：
  
  

	- 通过访问博客地址，已经可以看到我们新加入的内容，已经自动部署更新到站点了！✌🏻

### 4. 查看脚本执行日志

在我们的 webhooks.php 中，执行 git pull 脚本的时候，还有一段日志记录，便于知晓谁对网站对了什么！

**git_webhook_log.txt**



- git_webhook_log.txt 是在 webhooks.php 中记录的日志文件，你可以自行扩展其他需要输出的内容。

### 5. 查看webhooks推送日志





- 每一次 webhooks 执行时，都会有对应的记录，来告诉你本次代码推送是否被回调成功。并且在日志中，你还可以看到 webhooks 向你推送的内容 JSON 文件内容，你可以从中获取需要的信息，比如这是谁推送的、在哪个分支推送的、推送的文件有哪些等等。
- 这里也截取了一段推送的 JSON，其余信息你可以在推送记录中自己查看了。

## 七、总结

- 本章节我们带着大家彻底的把 webhooks 的使用走了一遍，也让需要此技术的小伙伴可以让自己的站点部署变更的更加`聪明一些`。当然自己做记录也帮助了一些师弟和小姐姐！
- 那么现在如果你手里有服务器正在吃灰不知道怎么用起来，现在可以折腾起来了，因为傅哥给你录好了入门视频、写好了操作文章，那么不要等待了，上吧！年轻人！课程链接：[https://space.bilibili.com/15637440/channel/seriesdetail?sid=479958](https://space.bilibili.com/15637440/channel/seriesdetail?sid=479958)
- 最后，如果你还没有服务器，那么赶紧搞一个吧，趁着还有活动🔥 链接：[https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=11388&recordId=1033318&userCode=is4kfbdt](https://www.aliyun.com/minisite/goods?taskPkg=1111ydsrwb&pkgSid=11388&recordId=1033318&userCode=is4kfbdt)

---

### Md Devops 2022 03 04 教小白使用 Docsify，搭建一个贼简单的所见即所得博客！ (`docs/md/devops/2022-03-04-教小白使用 docsify，搭建一个贼简单的所见即所得博客！.md`)

---
title: 教小白使用 docsify，搭建一个贼简单的所见即所得博客！
lock: need
---

# 教小白使用 docsify，搭建一个贼简单的所见即所得博客！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、前言

`看我博客挺好，你也想整一个？`

有粉丝伙伴问小傅哥，你那博客：[https://bugstack.cn](https://bugstack.cn) 挺好的我也想整一个，面试写到简历上`还能加分`，也是给自己建设影响力的东西。

不过我没有自己的域名，也没有一些云服务器，还不太会前端的玩意。之后搞的太复杂我又没有时间维护，那有没有简单点的方式，就能搞一个这样博客呢？

---

那当然有哇，你傅哥玩过的博客类型那可多了去了，包括：hexo、vuepress、jekyll、docsify等，这些都能满足你搭建博客的需求。但能满足小白使用的，我强烈推荐 docsify 这货简直是傻白甜都能使用，直接在 GitHub/Gitee 维护一个文档仓库，就可以拥有一个漂亮、简单、好用，易于维护和所见即所得的博客。

**为什么不用 CSDN、掘金、简书？**

当然可以用(`扩大影响力`)，只不过这些都不是原稿存放平台，你的内容输出需要被随心所欲的维护和积累，以及将来需要的时候还可以放置到任何一个其他平台。而你写在 GitHub 仓库，就是最原始的那一份，其他的都是备份传播，这样更有益于你来沉淀、积累和分享。

接下来小傅哥就教你构建这样一个博客，因为我已经帮你准备好了博客模板，所以在这个过程中，你只要跟着步骤，点点点，就部署完事了。**那整吧**，`咱们走起`！

## 二、docsify 介绍



docsify 可以快速帮你生成文档网站。不同于 GitBook、Hexo 的地方是它不会生成静态的 .html 文件，所有转换工作都是在运行时。如果你想要开始使用它，只需要创建一个 index.html 就可以开始编写文档并直接部署在 GitHub Pages。官网：[https://docsify.js.org/#/zh-cn](https://docsify.js.org/#/zh-cn)

### 1. 目录结构



- docsify 的目录结构配置非常简单，如果你不需要修改的话，只是 `md` 目录编写文档，在 `_sidebar.md` 配置文章路径即可。
- `index.html` 用于配置一些网站的基础信息，包括：网站采集、留言板、地址等。
- `_coverpage.md` 用于配置博客首页的介绍信息和网站Logo等

### 2. md 说明



- 所有的文章内容，都是使用 MD 格式进行编写。放心你不会用到太复杂的内容，一个运营小姐姐都可以半天学会。
- MD 使用文档：[https://www.runoob.com/markdown/md-tutorial.html](https://www.runoob.com/markdown/md-tutorial.html)

## 三、快速搭建博客

这里给大家提供 `GitHub/Gitee` 两种仓库来搭建博客，方便有些小白访问 GitHub 费劲也能用 Gitee 搭建博客。

- 仓库：[https://github.com/fuzhengwei/fuzhengwei.github.io](https://github.com/fuzhengwei/fuzhengwei.github.io)
- 说明：这是一个 docsify 的博客仓库地址，一些必要的简单配置信息小傅哥已经帮你处理好了，直接使用即可。

### 1. GitHub Page

- 优点：规范、部署不限制、自由度高、配置域名不收费
- 缺点：国内访问速度慢、仓库不能设置私有

#### 1.1 第一步：Fork



打开 [https://github.com/fuzhengwei/fuzhengwei.github.io](https://github.com/fuzhengwei/fuzhengwei.github.io) 点击 fork 到自己的仓库。

#### 1.2 第二步：配置



- 点击 Setting 进入 General 配置工程名称页面。
- **注意**：你必须把 `fuzhengwei.github.io` 修改为你的名称 `xxx.github.io` 这里的 xxx 就是你的GitHub的名称，也是 https://github.com/{xxxx} 链接后面的名称，不要修改错了，否则你就失败了。

#### 1.3 第三步：开启



- 点击 Setting 进入 Page 页面
- 按照上图修改博客资源空间到 `docs` 文件夹下，这个步骤是选择博客空间地址，记得不要配置错了。

#### 1.4 第四步：访问

好了，当你在配置后看到已经提醒你 `Your site is published at https://fuzhengwei.github.io/` 证明你成功了，你可以访问自己的博客地址了。PS：这里要 `xuewei` 的等一下，因为初始化有一个过程，正在编译稍后就可以访问了。

### 2. Gitee Page

- 优点：访问速度快、博客仓库可以设置私有
- 缺点：不能配置自己的域名，需要上传身份信息后才可以使用

#### 2.1 第一步：导入

与使用 GitHub 不同，这里是在 Gitee 中导入博客仓库，如下：



- 进入导入工程页面：[https://gitee.com/projects/import/url](https://gitee.com/projects/import/url) - 也可以从 gitee 右上角的 `+` 号进入。
- 复制博客模板： [https://github.com/fuzhengwei/fuzhengwei.github.io](https://github.com/fuzhengwei/fuzhengwei.github.io) 粘贴到 `Git 仓库 URL` 即可。
- 修改`仓库名称`、`路径`，为你的 gitee 账号名称，我这里的名称为 `yamiedei`，你复制自己的就可以了。

#### 2.2 第二步：配置



- 从 `服务` 的 `Gitee Pages` 进入即可进入配置博客页面。
- 不过由于大家基本都是初次使用 Gitee Pages 它会要求你上传认证信息，一天内审核完成。

#### 2.3 第三步：认证



- 如果你到了这个页面，可以提交资料后，第二天再继续了。

#### 2.4 第四步：开启



- 如果以上步骤都完事了，接下来你就可以开启自己的博客了，同样会给你一个博客地址，每次上传新的文章点击更新即可。

## 四、总结

`程序员，为什么要写博客？`

我，`软件工程`毕业？ 上学时觉得，毕了业就是开发工程师，但没想到工作些年还成了 PPT 工程师。

为啥呢？因为写代码只是作为一个程序员的最基本能力，如果还想继续在这条路上往前走，就需要有；提炼逻辑能力，制定标准手段、落地执行方案，而这一步步的推进都需要，就是将你的思考转换为可以看得见的内容，无论它是PPT、拓扑图、流程图还是思维导图，总之你需要一个合适的工具来表述你的想法，与沟通者最低成本完成消息传递和确认执行。

那么对于程序员来说，这个代码之外的能力成长，更好的方式则是`编写博客`、`记录分享`、`积累沉淀`，通过这样一个过程来不断的完善自己在内容表述上的能力，以及拓宽和拉伸自己的技术栈体系。

好嘞，现在你也拥有了一个可以像维护代码仓库一样的文档博客，并且随着你的学习过程，不断的完善、补充、沉淀，慢慢你终将会成为一名优秀的码农大佬。加油！

如果你已经搭建好了，可以在评论区留下你的博客地址哦！

---

### Md Devops 2023 03 25 免费部署部署ChatGPT (`docs/md/devops/2023-03-25-免费部署部署ChatGPT.md`)

---
title: 免费1年服务器，部署个ChatGPT专属网页版！
lock: need
---

# 免费1年服务器，部署个ChatGPT专属网页版！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

白皮袄个免费1年服务器，部署个ChatGPT专属网页版！

`api.openai.com port 443: Connection timed out` 你是不在调用 ChatGPT 接口的时候报错 443 了，哈哈哈，我的也是。当小傅哥发现自己开发的《ChatGPT AI 问答助手》已经不工作了，搜索了下为啥会 443 呢，原来是 openAI 的 API 域名已经 DNS 污染了，所以没法使用。

所以如果你仍需要**学习测试**使用，要不是找其他人做好的代理接口，要不就是买一台能调用 openAI 的海外服务器。但其实对于学习来说能白皮袄还花费这个钱干嘛！所以小傅哥今天给粉丝伙伴分享个，能免费使用1年稳定的云服务器。第二年再重新申请就可以。

**这里小傅哥先部署了一个 ChatGPT Web**：[http://chatgpt.itedus.cn/](http://chatgpt.itedus.cn/) - 以下文章有专门的部署教程。

<div align="center">
	<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-20.png?raw=true" width="950px"/>
</div>

## 一、这是什么服务器？

国内我们知道有阿里云、腾讯云、华为云、百度云、京东云，而国外有亚马逊旗下的 AWS 云，并且重点来了，AWS 是有免费的云服务的，任何人都可以获得一台。`其实以前就听说有 AWS 免费云，但一直没当回事，现在才感觉真香！`

在 AWS 活动页，有一个免费套餐，这里有很多产品都可以免费使用，包括；云服务、数据库、函数计算、机器学习等。地址：[https://aws.amazon.com/cn/free](https://aws.amazon.com/cn/free)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-01.png?raw=true" width="450px">
</div>

这里小傅哥感兴趣的就是 Amazon EC2 云服务器，每个月免费750个小时。这一个月31天✖️24小时不也才744小时，所以这和免费有啥区别？🤔 **难道一天能加出来25个小时班？**

**另外这里有一些注意点**；
1. EC2 云服务器，只有1核1G，在安装 Docker、Portainer、以及一个 Java SpringBoot 应用程序后，运行正常&稳定。
2. 申请时需要用到银行卡，我自己有一个 VISA 的信用卡，直接注册的时候使用就可以。其他银行卡也OK。`有些营销文，为了卖服务器说乱扣费`，为此我专门去搜索了下关于 AWS 免费服务器会有坑不，以及自己验证了一段时间，检查账单以及服务器的运行程度，发现使用的很顺畅，不会有恶意扣费。
3. 使用到快到1年的时候，可以把服务停掉，并重新申请个账号就可以继续用1年了。

如果以上这些点你觉得没问题，那么就可以按照接下来的教程进行申请和使用了。因为 Amazon EC2 和国内的一些服务器使用风格略有差异，所以需要按照教程创建并使用实例。

## 二、怎么免费白皮袄？

### 1. 创建账号

地址：[https://portal.aws.amazon.com/billing/signup#/start/email](https://portal.aws.amazon.com/billing/signup#/start/email)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-02.png?raw=true" width="450px">
</div>

### 2. 登录账号

地址：[https://console.aws.amazon.com/console/home](https://console.aws.amazon.com/console/home)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-03.png?raw=true" width="450px">
</div>

### 3. 控制面板

地址：[https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/home](https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/home) - 搜索 IAM 并进入，就是控制面板了。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-04.png?raw=true" width="450px">
</div>

在创建 Amazon EC2 云服务器前，需要在控制面板中创建；用户组、用户、角色，这样在后面创建服务器的时候才能把用户信息给关联上。

#### 3.1 创建用户

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-05.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-06.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-09.png?raw=true" width="750px"/>
</div>

- 地址：[https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/users](https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/users)
- 说明：首先你需要在IAM控制面板下的访问管理中的用户下，创建一个自己的用户。你可以创建用户名为 admin 或者其他。

#### 3.2 创建用户组

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-07.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-08.png?raw=true" width="750px"/>
</div>

- 地址：[https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/groups/create](https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-2#/groups/create)
- 说明：在用户组的创建中，写上组名、添加上刚才创建的用户admin，之后再搜索`AdministratorAccess`为这个组的用户进行授权。

### 4. 部署实例

#### 4.1 创建密钥对

这里需要先创建一个密钥对，之后再创建应用实例的时候把密钥对关联上去。同时密钥对也是用作本地 SSH 登录的一个重要凭证，否则不能登录。另外这里创建完密钥对，会自动下载到本地，你需要保存好。

地址：[https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#KeyPairs:](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#KeyPairs:) - EC2 管理控制台。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-10.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-11.png?raw=true" width="750px"/>
</div>

- 创建完成后，会自动下载一个名为 `admin_key.pem` 的文件，保存好它，后面用。

#### 4.2 创建安装组

用于访问服务器的端口都需要在安全组中开通，比如 SSH 22、Portainer 9000、Docker 2375 所以需要自己创建一个安全组。

地址：[https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#SecurityGroups:](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#SecurityGroups:)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-12.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-13.png?raw=true" width="750px"/>
</div>

- 以后你想控制各个端口的访问，就在安全组中操作就可以了。

#### 4.4 启动新实例

如果你比较粗鲁，刚一进来 AWS 就创建了实例，但发现用户也不对，权限也不对用不了。没关系可以把它终止掉，之后重新启动新实例。

地址：[https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#Instances:](https://us-east-2.console.aws.amazon.com/ec2/home?region=us-east-2#Instances:)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/dev-ops-230321-14.png?raw=true" width="750px"/>
</div>

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-15.png?raw=true" width="750px"/>
</div>

如果在使用中把自己的应用实例搞坏了，没关系。直接干掉它，重新启动新实例就可以了。

### 5. 连接实例

Amazon EC2 云服务器提供了 EC2 在线连接、会话管理器、SSH 客户端、EC2 串行管理器。我们这里主要用在线的和 SSH 客户端。

| **EC2 Instance Connect**                              | SSH 客户端                                            |
| ----------------------------------------------------- | ----------------------------------------------------- |
|  |  |

- EC2 在线连接，直接点上连接就可以了。SSH 客户端需要按照引导进行操作。

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-18.png?raw=true" width="950px"/>
</div>

通过此方式就可以本地连接了，还是非常方便的。如果你有连接工具也可以配置到工具中操作。

## 三、部署应用耍起来！

### 1. 安装 Docker 

```java
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

yum list docker --showduplicates | sort -r

sudo yum install docker

sudo systemctl start docker

systemctl enable docker

docker --version
```

### 2. 配置远程链接

```java
vim /usr/lib/systemd/system/docker.service
在ExecStart=/usr/bin/dockerd-current 后面加上 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \
# 重新加载配置文件
systemctl daemon-reload
# 重启启动
systemctl restart docker
```

### 3. 部署网页版 ChatGPT

| 方式                                              | 免费？ | 可靠性     | 质量     |
| ------------------------------------------------- | ------ | ---------- | -------- |
| `ChatGPTAPI(gpt-3.5-turbo-0301)`                  | 否     | 可靠       | 相对较笨 |
| [`ChatGPTUnofficialProxyAPI(网页 accessToken)`](https://chat.openai.com/api/auth/session) | 是     | 相对不可靠 | 聪明     |

**通过以下方式，你可以自己部署一个网页版的 ChatGPT，让自己使用。** 注意：OPENAI_API_KEY 需要申请

- 海外服务器；`docker run --name chatgpt-web -d -p 3002:3002 --env OPENAI_API_KEY=sk-6cPOiRgKmIcMA**** chenzhaoyu94/chatgpt-web`
- 海内服务器；`docker run --name chatgpt-web -d -p 3002:3002 --env OPENAI_API_KEY=sk-6cPOiRgKmIcMA**** --env OPENAI_API_BASE_URL=https://open2.aiproxy.xyz chenzhaoyu94/chatgpt-web` - 需要添加代理

**也可以不使用Key方式部署**，这个方式的好处是免费，都免费！

- docker run --name chatgpt-web -d -p 3002:3002 --env OPENAI_ACCESS_TOKEN=【从这里获取 https://chat.openai.com/api/auth/session】 chenzhaoyu94/chatgpt-web

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-20.png?raw=true" width="950px"/>
</div>

- 开源项目：[https://github.com/Chanzhaoyu/chatgpt-web](https://github.com/Chanzhaoyu/chatgpt-web) - 点个 Star 支持作者
- 开源代理：[https://github.com/geekr-dev/openai-proxy](https://github.com/geekr-dev/openai-proxy) - 点个 Star 支持作者

### 4. 部署 ChatGPT 问答助手

- 地址：[https://github.com/fuzhengwei/chatbot-api](https://github.com/fuzhengwei/chatbot-api)
- 视频：[https://bugstack.cn/md/project/chatbot-api/chatbot-api.html](https://bugstack.cn/md/project/chatbot-api/chatbot-api.html)
- 注意：通过 IDEA 打开 chatbot-api 并在 IDEA 配置 Docker，这样就可以直接部署应用了。这些内容在视频里都有手把手操作。

<div align="center">
		<img src="https://bugstack.cn/images/article/devops/dev-ops-230321-19.png?raw=true" width="950px"/>
</div>

---

### Md Devops 2023 04 18 Docker (`docs/md/devops/2023-04-18-docker.md`)

---
title: Docker
lock: need
---

# Docker 环境配置

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

- 官网：[https://www.docker.com](https://www.docker.com/) - Mac、Windows、Linux
- 介绍：Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中，然后发布到任何流行的 Mac、Linux或Windows操作系统的机器上，也可以实现虚拟化。容器是完全使用沙箱机制，相互之间不会有任何接口。总之它加快构建、共享和运行现代应用程序的速度。

## 一、基础安装

### 1. 查看系统的内核版本

```java
[root@CodeGuide ~]# uname -r
4.18.0-80.11.2.el8_0.x86_64
```

- `uname -r`
- x86 64位系统，如果是32位是不能安装 docker 的

### 2. yum 更新到最新版本

```java
[root@CodeGuide ~]# sudo yum update
Last metadata expiration check: 1:15:10 ago on Sat 27 Nov 2021 04:22:53 PM CST.
Dependencies resolved.
Nothing to do.
Complete!
```

- `sudo yum update`
- 看到显示 `Complete` 就代表完成了，整个过程需要 5-10 分钟左右

### 3. 安装Docker所需的依赖包

```java
[root@CodeGuide ~]# sudo yum install -y yum-utils device-mapper-persistent-data lvm2
Last metadata expiration check: 1:16:16 ago on Sat 27 Nov 2021 04:22:53 PM CST.
Package yum-utils-4.0.21-3.el8.noarch is already installed.
Package device-mapper-persistent-data-0.9.0-4.el8.x86_64 is already installed.
Package lvm2-8:2.03.12-10.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to
```

- `sudo yum install -y yum-utils device-mapper-persistent-data lvm2`
- 看到显示 `Complete` 就代表完成了，整个过程需要 1-3 分钟左右

### 4. 设置Docker的yum的源

```java
[root@CodeGuide ~]# sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
```

- sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 鉴于国内网络问题，强烈建议使用国内源。以下是阿里云的软件源。**如果是海外如AWS云就不要设置yum源**

```bash
sudo yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
```


### 5. 查看仓库所有Docker版本

```java
[root@CodeGuide ~]# yum list docker-ce --showduplicates | sort -r
Installed Packages
docker-ce.x86_64               3:20.10.9-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.8-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.7-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.6-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.5-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.4-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.3-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.2-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.1-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.11-3.el8                docker-ce-stable 
docker-ce.x86_64               3:20.10.11-3.el8                @docker-ce-stable
docker-ce.x86_64               3:20.10.10-3.el8                docker-ce-stable 
docker-ce.x86_64               3:20.10.0-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:19.03.15-3.el8                docker-ce-stable 
docker-ce.x86_64               3:19.03.14-3.el8                docker-ce-stable 
docker-ce.x86_64               3:19.03.13-3.el8                docker-ce-stable 
Docker CE Stable - x86_64                       7.1 kB/s | 3.5 kB     00:00    
Available Packages
```

-  yum list docker-ce --showduplicates | sort -r
- 这里可以看到你能安装的最新版本

### 6. 安装Docker

```java
[root@CodeGuide ~]# sudo yum install docker
```

- 安装默认最新版本的 Docker

```java
[root@CodeGuide ~]# sudo yum install <FQPN>
```

- 安装指定版本，例如：sudo yum install docker-ce-20.10.11.ce

### 7. 安装Docker-Compose

#### 7.1 正常安装

```shell
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```

#### 7.2 离线安装

```shell
# 下载；docker-compose-`uname -s`-`uname -m` 查看版本；https://github.com/docker/compose/releases/tag/v2.18.1
# 重命名
mv docker-compose-Linux-x86_64  docker-compose
# 加入执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 查看docker-compose版本
docker-compose -v
```

```java
[root@dev-ops bin]# sudo chmod +x /usr/local/bin/docker-compose
[root@dev-ops bin]# docker-compose -v
Docker Compose version v2.18.1
```

### 8. 启动Docker并添加开机自启动

```java
[root@CodeGuide ~]# sudo systemctl start docker
```

- 启动 Docker

```java
[root@CodeGuide ~]# systemctl enable docker
```

- 设置开机启动 Docker

### 9. 查看 Docker 版本

```java
[root@CodeGuide ~]# docker --version
Docker version 20.10.11, build dea9396
```

### 10. 卸载 Docker

```java
[root@CodeGuide ~]# sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
```

### 11. Docker 常用命令

```java
[root@CodeGuide ~]# docker --help				#Docker帮助
[root@CodeGuide ~]# docker --version			#查看Docker版本
[root@CodeGuide ~]# docker search <image>		#搜索镜像文件，如：docker search mysql
[root@CodeGuide ~]# docker pull <image>		#拉取镜像文件， 如：docker pull mysql
[root@CodeGuide ~]# docker images				#查看已经拉取下来的所以镜像文件
[root@CodeGuide ~]# docker rmi <image>		#删除指定镜像文件
[root@CodeGuide ~]# docker run --name <name> -p 80:8080 -d <image>		#发布指定镜像文件
[root@CodeGuide ~]# docker ps					#查看正在运行的所有镜像
[root@CodeGuide ~]# docker ps -a				#查看所有发布的镜像
[root@CodeGuide ~]# docker rm <image>			#删除执行已发布的镜像
```

### 12. 设置国内源

阿里云提供了镜像源：[https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors) - 登录后你会获得一个专属的地址。

使用以下命令来设置 Docker 国内源：- 或者你可以通过 `vim /etc/docker/daemon.json` 进入修改添加 registry-mirrors 内容后重启 Docker

```
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://***替换为你的地址***.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```

这个命令会创建一个 `/etc/docker/daemon.json` 文件，并将国内源的配置写入其中。然后你只需要重启 Docker 服务即可使配置生效，可以通过运行 `sudo systemctl restart docker` 命令来重启 Docker 服务。

---

### Md Devops 2023 04 18 Portainer (`docs/md/devops/2023-04-18-portainer.md`)

---
title: Portainer
lock: need
---

# Portainer 环境配置

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

- 官网：[https://www.portainer.io/](https://www.portainer.io/)
- 介绍：在任何数据中心、云、网络边缘或 IIOT 设备的 Kubernetes、Docker、Swarm 和 Nomad 上，在几分钟内部署、配置、故障排除和保护容器。 

## 一、基础安装

### 1. 拉取最新的 Portainer

```java
[root@CodeGuide portainer]# docker pull portainer/portainer
Using default tag: latest
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete 
49d59ee0881a: Pull complete 
a2300fd28637: Pull complete 
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
docker.io/portainer/portainer:latest
```

- docker pull portainer/portainer
- 拉取 portainer

### 2. 安装和启动

```java
[root@CodeGuide]# docker run -d --restart=always --name portainer -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
```

### 3. 访问 Portainer

- 地址：[http://39.96.*.*:9000/](#)
- 操作：登录后设置你的用户名和密码，并设置本地Docker即可，设置完成后，如下

<div align="center">
	<img src="https://bugstack.cn/images/article/devops/dev-ops-portainer-230418-01.png?raw=true" width="950px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/article/devops/dev-ops-portainer-230418-02.png?raw=true" width="950px"/>
</div>

## 二、链接服务

地址：[http://180.76.119.142:9000/#!/wizard/endpoints/create?envType=dockerStandalone](http://180.76.119.142:9000/#!/wizard/endpoints/create?envType=dockerStandalone)

<div align="center">
	<img src="https://bugstack.cn/images/article/devops/dev-ops-portainer-230418-01.png?raw=true" width="950px"/>
</div>

```shell script
docker run -d \
  -p 9001:9001 \
  --name portainer_agent \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  portainer/agent:2.16.2
```

---

### Md Devops 2023 04 18 Tool (`docs/md/devops/2023-04-18-tool.md`)

---
title: Tool
lock: need
---

# Tool 工具整理

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## SSH 客户端工具

1. [nuoshell](https://www.nuoshell.com/) - 一款免费的专门为 Mac OSX 系统打造的，集多功能于一身的 SSH 客户端工具。
2. [termius](https://termius.com/) - 含付费Plus功能，但基础功能已够用。可以支持电脑和移动设备使用，包括 SFTP 功能。
3. [WindTerm](https://github.com/kingToolbox/WindTerm) - 专业的跨平台SSH/Sftp/Shell/Telnet/串口终端。完全免费，可用于商业和非商业用途，无任何限制。 
4. [SSH Config Editor](http://hejki.tilda.ws/ssheditor) - 一款用于管理OpenSSH ssh客户端配置文件的工具。
5. [ZOC](https://www.emtec.com/zoc/) - ZOC • 适用于 macOS 和 Windows 的 SSH 客户端和终端仿真器。
6. [SecureCRT](https://mobaxterm.mobatek.net/)  - 带有 X11 服务器、选项卡式 SSH 客户端、网络工具等的增强型 Windows 终端。
7. [Electerm](https://github.com/electerm/electerm) - 开源终端/ssh/telnet/serialport/sftp客户端(linux, mac, win)。
8. [PuTTY](https://www.putty.org/) - PuTTY 是一个 SSH 和 telnet 客户端，最初由 Simon Tatham 为 Windows 平台开发。PuTTY 是开源软件，提供源代码，由一群志愿者开发和支持。
9. [FinalShell SSH工具](http://www.hostbuf.com/t/988.html) - FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工具,充分满足开发,运维需求.
10. [Xterminal](https://www.terminal.icu/) - 不仅是强大的SSH工具，更提供本地控制台，以及更多即将推出的开发相关功能，让您专注于创造卓越的代码。

## MySql 客户端工具

1. [DBeaver Community - Free Universal Database Tool](https://dbeaver.io/download/) - `MySQL、Azure SQL Server、Apache Ignite...`
2. [Sequel Pro](https://www.sequelpro.com/) - `不太推荐了，有bug`
3. [Sequel Ace](https://apps.apple.com/us/app/sequel-ace/id1518036000?ls=1) - `推荐，是 Sequel Pro 的扩展维护版。免费好用！`
4. [Navicat](https://www.navicat.com.cn/products) - `同好用的就是收费，破解的在公司用可不行`
5. [IntelliJ Datagrip](https://www.jetbrains.com/zh-cn/datagrip/) - `免费使用30天`

---

个人在使用 nuoshell、termius 挺稳又好用。

---

### Md Devops 2024 01 30 Vuepress Resume Blog (`docs/md/devops/2024-01-30-vuepress-resume-blog.md`)

---
title: 搭建博客，展示过往经历。让面试官更了解我，面试更稳了！
lock: need
---

# 搭建博客，展示过往经历。让面试官更了解我，面试更稳了！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1455955421&bvid=BV1ri421a7Aj&cid=1592730106&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

不少小伙伴都想放在简历上放一个动态博客链接，展示自己的过往技术经历和可运行的项目展示。通过这样的方式提高自己在面试中的竞争力。但因为没做过，又不知道从哪开始，找的一些案例教程又都很复杂。所以，小傅哥来帮你一下，让你SoEasy的搞定这东西。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/chatgpt/chatgpt-extra-230905-01.png?raw=true" width="200px">
</div>

当这个男人👨🏻准备下手的时候，一切技术将变得简单、容易，好理解！

我把本次的分内容定义为简历博客，并已经做好了博客的框架（[vuepress](https://theme-hope.vuejs.press/zh/)）和内容案例，以及部署需要的Nginx配置。如果你需要部署到线上，那么需要准备一台云服务器（[2c2g 50元/1年](https://gaga.plus/yun.html)）。另外你还可以注册一个域名（ICP备案2周），这样就可以通过域名访问你的专属博客了。【要我说，每个程序员👨🏻‍💻都应该有一个自己的域名，有了它你才有了做一些事情的可能】。**接下来我会带着你搭建一个如图所示的个人简历博客**

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-01.png?raw=true" width="700px">
</div>

那么，接下来小傅哥就带着你，完成下简历博客的搭建。

>文末提供了8个Java实战项目，嘎嘎提升简历竞争力。💐

## 一、搭建准备

- 简历博客项目：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-blog](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-blog)
- 一台云服务器，2c2g 推荐 50元/1年 [https://gaga.plus/yun.html](https://gaga.plus/yun.html)
- 云服务器搭建 Docker、安装 Portainer 教程地址（包括学习视频）：[https://bugstack.cn/md/road-map/docker.html](https://bugstack.cn/md/road-map/docker.html)
- 域名和域名备案（ICP备案2周），未购买也可以完成本节课程的操作。
- SSL 申请，如果有域名了，可以申请免费的 SSL 让域名地址支持 HTTPS。申请地址：[https://yundun.console.aliyun.com/?p=cas#/certExtend/free/cn-hangzhou](https://yundun.console.aliyun.com/?p=cas#/certExtend/free/cn-hangzhou)
- Node.js 安装，地址：[https://nodejs.org/en/download](https://nodejs.org/en/download) - `选择自己机器适配的版本安装即可`

## 二、项目说明

这里小傅哥已经把博客框架、内容案例、部署博客的环境，都准备好了。你只需要下载到本地就可以使用。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-02.png?raw=true" width="400px">
</div>

本博客采用 [VuePress Theme Hope](https://theme-hope.vuejs.press/zh/) 模板进行搭建。当你能完成部署本博客后，还可以参考模板做一些其他的扩展以及各类喜欢插件的安装。

- src 目录下，为博客的框架模板和已经写好的案例。在 `package.json`中有一个 `docs:build` 用于构建，还有一个 `docs:dev`用于本地启动测试。
- dev-ops 提供的是博客的部署，这里的 docker-compose.yml 是 Docker 执行脚本安装 Nginx 环境。
- 小傅哥在 `src/.vuepress-> config.ts`文件中下配置了把项目 build 到 nginx/html 文件夹。这样可以更加方便我们部署。

## 三、部署项目

当你把 xfg-dev-tech-blog 项目检出到本地，使用 IntelliJ IDEA 或者 WebStrom 工具打开后。会提示你执行 npm install 安装环境。如果没有提示你也可以自己在项目 Terminal 下执行。执行完安装就可以做博客的部署了。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-03.png?raw=true" width="550px">
</div>

### 1. 构建项目

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-04.png?raw=true" width="550px">
</div>

- 打开项目的 `package.json`里面有`构建`和`运行`命名。
- 构建的操作会把工程打包为 HTML 文件写入到 dev-ops/nginx/html 文件夹下。
- 运行的操作会直接本地启动服务，启动后你可以在本地预览。这样你在修改一些内容的时候也可以随时看到效果。

### 2. 构建结果

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-05.png?raw=true" width="750px">
</div>

- 如步骤操作，完成构建。当你看到 `dev-ops/nginx/html` 下有对应的一堆文件了，说明构建成功了。

### 3. Nginx 配置

对于 Nginx 的配置提供了3种方式，分别包括；IP访问、HTTP域名访问、HTTPS域名访问。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-06.png?raw=true" width="350px">
</div>

#### 1. localhost.conf

这个配置方式为了方便，没有域名的伙伴们测试使用。也就是你部署后可以直接通过IP进行访问。

```shell
server {
    listen       80;
    listen  [::]:80;

    location / {
       root /usr/share/nginx/html;
       index index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

}
```

- 直接把 80 请求转发到本地的根目录地址的 html 文件上即可

#### 2. http.blog.conf

##### 2.1 配置域名解析

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-07.png?raw=true" width="550px">
</div>

- 如果你有云服务器和域名，那么可以先如图，配置下域名解析地址。

##### 2.2 nginx 脚本

```shell
server {
    listen       80;
    listen  [::]:80;
    server_name  blog.gaga.plus;

    location / {
       root /usr/share/nginx/html;
       index index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

}
```

#### 3. https.blog.conf

如果你有域名那么还可以配置免费的ssl验证，配置完成后把 ssl key、pem 文件放到 dev-ops/nginx/ssl 文件夹下并上传到云服务器上。详细介绍：[https://bugstack.cn/md/devops/2023-04-18-nginx.html#_4-1-%E5%88%9B%E5%BB%BA%E8%AF%81%E4%B9%A6](https://bugstack.cn/md/devops/2023-04-18-nginx.html#_4-1-%E5%88%9B%E5%BB%BA%E8%AF%81%E4%B9%A6)

```shell
server {
    listen       80;
    listen  [::]:80;
    server_name  blogs.gaga.plus;

    rewrite ^(.*) https://$server_name$1 permanent;
}

server {
    listen       443 ssl;
    server_name  api.gaga.plus;

    ssl_certificate      /etc/nginx/ssl/blogs.gaga.plus.pem;
    ssl_certificate_key  /etc/nginx/ssl/blogs.gaga.plus.key;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
         root /usr/share/nginx/html;
         index index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

- 这个方式就是配置 ssl 的方式。

### 4. 上传文件

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-08.png?raw=true" width="750px">
</div>

- 小傅哥这里使用的是 [https://termius.com/](https://termius.com/) 连接云服务器的 SSH 工具，自带 SFTP 。`你也可以使用其他 SSH/FTP 工具`
- 通过这个工具，连接云服务器，并把我们在工程下创建的 `dev-ops` 上传到云服务器端。

### 5. 服务启动

接下来，你只需要在云服务器进入到 dev-ops 文件夹下，执行脚本 `docker-compose -f docker-compose.yml up -d` 即可完成部署。

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-09.png?raw=true" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-10.png?raw=true" width="750px">
</div>

- 在你初次部署的时候，会拉取 Nginx 镜像。拉取完成后则会自动部署。
- 部署完成后可以进入到 portainer 中查看 nginx 运行，以及进入到日志中查看运行情况。

### 6. 访问博客

- IP地址：[http://117.72.37.243/](http://117.72.37.243/)
- HTTP地址：[http://blog.gaga.plus/](http://blog.gaga.plus/)
- HTTPS地址：[https://blogs.gaga.plus/](https://blogs.gaga.plus/)

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-11.png?raw=true" width="950px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-12.png?raw=true" width="950px">
</div>

**全部完成撒花 💐** 现在你就可以在简历上挂一个自己的博客了，还可以在博客中秀出自己的技术肌肉💪🏻，赢得面试官的青睐！

>当然，有了简历博客，最好配有一套对应的高质量实战项目，撑起简历的技术度。那些CRUD/XXX管理系统，现在是越来越没竞争力了。早点学一些，每天积累一点，就能让自己有更多的选择。

## 四、实战项目

小傅哥工作10年+，深刻感受到在不同阶段(毕业~3年，3年~5年、5年+)都要有对应的能力，才能踏上换乘的列车。为了让自己的职业生涯走的更加稳妥，就不要只把自己当成满足工作需要的工具。早些积累、早些积累自己的技术栈体系闭环。这是非常重要的！！！

>小傅哥把工作中的技术经验，陆续的编写出对应的博客和实战项目，整整写了3年多。这些内容可以让一个研发小白成长为技术大牛！

<div align="center">
    <img src="https://bugstack.cn/images/article/devops/xfg-dev-tech-blog-13.png?raw=true" width="950px">
</div>

**加入学习 https://gaga.plus**

>[🧧加入学习](https://bugstack.cn/md/zsxq/other/join.html)

**注意📢**，加入星球后你可以申请加入星球VIP群，获得高质量技术交流。此外星球的所有内容，都从星球的**课程入口**进入，里面做了非常细致的归档。

---

### Md Devops 2024 03 23 Yun (`docs/md/devops/2024-03-23-yun.md`)

---
title: 云服务器
lock: need
---

# 云服务器，2c2g 1年50、2c4g 1年126、4c16g 1月26.5

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

不少学习编程的伙伴，都有把项目部署到云服务器，实践真实场景锻炼编程能力的诉求。包括；`云服务器配置`、`上线环境安装`、`安全组开通`，`以及部署后的性能压测`。这些真实的操作都是非常能锻炼人的，只有做过才懂。**😂 这些年，小傅哥的云服务器费用，花费了上万块了都！但很值得，学习到手了很多东西。**

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-01.png" width="450px">
</div>

那云服务器有很便宜，很实惠的吗？🤔

与过去云服务厂商不多的时候相比，现在的云服务器市场很卷，所以最实惠的也就是咱们这样的小用户。但凡自己或家里有几个没注册过的新用户，都能拿到这么便宜、实惠、好用的云服务器。

**💐 2c2g 1年 50元、2c4g 1年126元【推荐】、4c16g 3个月80元，2c4g 3年 558【推荐】、2c8g 3年998** —— 优惠链接：[https://618.gaga.plus/](https://618.gaga.plus/) 

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-02.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-07.png" width="750px">
</div>

优惠链接：[https://yun.xfg.plus/](https://yun.xfg.plus/) - 我把最优惠的SKU做了汇总，你可以进入选择。点击后，还可以继续选配置。如果项目部署的较大，不要选2c2g。

>小傅哥，云服务器我有手✋🏻，我会买。那云服务器的使用教程有吗，能锻炼技能上云的项目有吗？🤔 —— 当然！有！你傅哥不就是卷这些的吗，管项目都卷了11万行代码给大家。

## 云服务器教程

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-03.png" width="550px">
</div>

- 关于云服务器的配置选择、环境安装、空间占用等各类实战的技巧，我都做了相关的视频，你只要跟着搞就可以。一次学习，永久收获！
- 注意：日常简单测试安装个轻量的环境，2c2g 会占用到 60%，长期使用推荐 2c4g。分布式所有环境（mysql、redis、nacos、elk、普罗米修斯、canal、前后端应用）需要 2c8g。

## 实战项目系列

小傅哥就是个实战派，1年、3年、2c2g、2c4g、2c8g 的服务器，我都有买，分别部署了不同的项目，自己可以锻炼，也让大家可以学习。地址：[https://gaga.plus](https://gaga.plus) - 进入后可以看到实战项目和部署演示。

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-04.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/article/about/jdyun-05.png" width="750px">
</div>

在 `嘎嘎强 gaga.plus` 中有大量的实战项目，你都可以学习部署到云服务器上。而且会专门写好的教程和录制的手把手视频，教你从服务器选择、环境安装、应用构建、镜像部署、监控配置、应用压测，一步步带着你做。

## 嘎嘎实惠加入

小傅哥是一个大厂的架构师，经常会带着伙伴们，卷这些实际场景中非常有必要的技术。也会带着伙伴实战项目，这些项目也都是来自于互联网大厂中真实的业务场景，所有学习这样的项目无论是实习、校招、社招，都是有非常强的竞争力。别人还在玩玩具，而你已经涨能力！

>🧧在小傅哥星球「码农会锁」有8个实战项目，每个都是从0到1开发并提供简历模板和面试题，并且还在继续开发，后续还将有更多！价格嘎嘎实惠，早点加入，早点提升自己。项目地址：https://gaga.plus

---

### Md Other Guide To Reading (`docs/md/other/guide-to-reading.md`)

---
title: 编码指南
---

# bugstack虫洞栈 | 程序员的编码指南 🔥

>你好，我是小傅哥，[《重学Java设计模式》](https://item.jd.com/13218336.html)、[《手写MyBatis：渐进式源码实践》](https://item.jd.com/13811216.html) 图书作者，一线互联网 Java 工程师、架构师。

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=298298421&bvid=BV1FF41137q5&cid=578551972&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

我是一个着迷于技术，又喜欢不断折腾的技术活跃者，从13年毕业到进入互联网，开发过交易、营销类项目，实现过运营、活动类项目，设计过中间件，组织过系统重构，发表过数十篇技术专利。不仅从事业务系统的开发工作，也经常做一些字节码插桩类的设计和实现，对架构的设计和落地有丰富的经验。在热衷于Java语言的同时，也喜欢研究中继器、I/O板卡、C#和PHP！

除此之外小傅哥并不只满足于CRUD搬砖，也关心业务、运营、产品、数据、测试、运维等各项知识体系的完善学习，就研发架构设计来讲，更全面的学习会更有利于做出更长远的架构设计。同时完善个人知识体系也更有利于个人成长。

所以你会看到小傅哥在工作之外的深夜、周末、假期会折腾于写文章、编小册、出书籍，并十分热情于对粉丝的交流、提问、解惑。并不深沉且少许逗比的我，希望我的沉淀，分享，也可以给你带来收获！

---

⏰ **提醒**：在接下来你对本博客的阅读中，如果遇到一些`内容`、`图稿`、`代码`等中的勘误都可以提交Issue或者PR的方式进行反馈，小傅哥会陆续进行完善，感谢您的支持；

- 贡献
  - Issue：[https://github.com/fuzhengwei/CodeGuide/issues](https://github.com/fuzhengwei/CodeGuide/issues)
  - PR：[https://github.com/fuzhengwei/CodeGuide/pulls](https://github.com/fuzhengwei/CodeGuide/pulls) - 你只需要在阅读文章的最下面找到`在 GitHub 上编辑此页`，即可完成克隆和提交PR
  
- 学习
  - 博客 [小傅哥虫洞栈](https://bugstack.cn/) 具备丰富的企业级实战技能，可以综合提高自己的全方面架构、技术、项目、运维，方面知识积累。
  - 项目 [星球「码农会锁」](https://bugstack.cn/md/zsxq/introduce.html) - 具有非常多的实战类业务项目、组件项目、开源项目等，☕️一顿饭钱的支持，突破技术瓶颈`！
  - 演示 [嘎嘎强，嘎嘎哒学](https://gaga.plus/) - 应用级实战项目运行演示平台。用户可以体验项目运行效果，并学习每个功能的实现方案。

- 其他
	- 考试：[100道八股题考试测验](https://bugstack.cn/md/zsxq/material/exam.html) —— 你可以尝试验证自己的能力，考题范围：数据结构、算法、源码、设计模式、系统架构、中间件、网络通信、实战项目、扩展问题
	- 本站为公众号往期文章整理的小册，关注`公众号`：[bugstack虫洞栈](https://bugstack.cn/images/personal/qrcode.png) 可以知晓最新推文，避免错过最近正在更新的技术系列文章。
	- 其他：如果你在学习本站内容遇到不能解决的问题，可以联系作者：`小傅哥`，微信：`fustack` - 交个朋友👬🏻，不要错过成为技术同好的机会。

<div align="center">
    <img src="https://bugstack.cn/images/system/zsxq/xingqiu-231018-01.png?raw=true" width="700px">
    <div style="font-size: 12px;"><a href="https://t.zsxq.com/Ja27ujq">星球介绍：码农会锁 - 实战项目「大营销平台、OpenAi、Lottery、Api网关等」、专属小册、问题解答、简历指导、架构图稿、视频课程</a></div>
</div>

## 一、本站知识阅览

我给自己在技术职业成长上，定位成一个能抗住`农夫三拳`的架构师，所以我在编写和输出的技术内容上，也是以数据结构、算法逻辑、设计模式、核心技术、系统架构、服务运维等方面的知识扩展技术广度和深度，并以实践验证的学习方式进行汇总内容编写文章。也希望这些成体系的技术系列内容能帮助你慢慢且踏实的成长起来。



而这几大块内容也是每一个较贵的 Java 程序员应该掌握的内容，可以包括：

- **编程路书**：开发一套[《Java简明学习路书》](https://bugstack.cn/md/road-map/road-map.html)，通过一个个小案例，为大家讲解这些技术栈的运用。帮助踏上这条路上的伙伴，以更简单明了的方式进入编程学习。最后再通过完整的项目实战，把这些技术栈串联起来运用。
- **Java&Spring**：以讲解Java、Spring核心知识为基础，用数学逻辑思维分析关于Java、Spring、Mybatis、Dubbo等核心源码技术内容。其中如[《Java 面经手册》](https://bugstack.cn/md/project/pdf/2021-01-26-Java%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8CPDF%E4%B8%8B%E8%BD%BD.html)是一本以面试题为入口讲解 Java 核心内容的技术书籍，书中内容极力的向你证实代码是对数学逻辑的具体实现。包括正在编写的[《手撸 Spring》](https://bugstack.cn/md/spring/develop-spring/2021-05-16-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Spring%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.html)通过手写简化版 Spring 框架，了解 Spring 核心原理。在手写的过程中会简化 Spring 源码，摘取整体框架中的核心逻辑，简化代码实现过程，保留核心功能，例如：IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。这些都程序员学习技术成长过程中非常重要的知识，如果能深入学习那么对以后的个人成长帮助非常大。
- **算法逻辑和数据结构**：这部分内容主要以Java源码为入手，讲解其中的数学知识，包括：扰动函数、负载因子、拉链寻址、开放寻址、斐波那契（Fibonacci）散列法还有黄金分割点的使用等等，这也正是[《Java 面经手册》](https://bugstack.cn/md/project/pdf/2021-01-26-Java%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8CPDF%E4%B8%8B%E8%BD%BD.html)的核心内容所在。
- **面向对象**：[《Java 设计模式》](https://item.jd.com/13218336.html)的知识是在Java基础铺平，数据结构、算法逻辑有了一定的了解后，在深入学习和使用的技术。同样是一个需求在学过设计模式后，也阅读了不少别人优秀的代码，那么在他实现需求的时候，会拆分出很多的接口和接口的继承、抽象类的职责隔离实现、具体业务模块的分层、功能服务组件的细化、具体实现过程中对设计模式的运用等等。这样的代码实现后会非常具有易扩展和可维护的特点，否则一篇的ifelse不是坑自己就是坑下一个人。
- **中间件**：可能很大一部分研发并不会接触到中间件，也不太可能有人告诉你可以使用中间件的方式解决一些实际遇到的问题。因为大部分时候你都会认为中间件只是公司专门部门的人写的，或者是技术大牛搞的，总之与你没关系。但其实代码知识对数学逻辑的具体实现，业务开发有业务开发的方式，[《Spring 中间件和开发》](https://bugstack.cn/md/project/springboot-middleware/2021-03-31-%E3%80%8ASpringBoot%20%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91%E3%80%8B%E4%B8%93%E6%A0%8F%E5%B0%8F%E5%86%8C%E4%B8%8A%E7%BA%BF%E5%95%A6%EF%BC%81.html)也只是对Spring的关于容器中一些特定接口和类的使用，具体的还是普通的逻辑代码，比如暴露服务、采集日志、监控系统等。但如果你能早些学到这样技术的核心思想，那么对于升值、加薪、跳槽，都是非常有帮助的。
- **通信专题**：其实Netty是一项非常重要的技术，比如在RPC服务实现中的Dubbo、或者MQ、以及很多时候的通信里都是能用到的技术。就连小傅哥的第一次面试大厂也是靠着对Netty的学习，刷进来的！所以小傅哥编写了很多Netty从基础入门讲解到核心原理，告诉你如何处理半包、粘包，怎样定义消息协议，并开发了一个基于Netty的仿微信聊天项目，这些技术内容你都可以在我的博客学习到学习到。
- **字节码编程**：这项技术可能大多数研发，哪怕35岁的，可能也不一定接触到。但这样的技术你却基本都用过，比如你的IDEA是购买的吗，你怎么给让它能用的！你用过一些非入侵的全链路监控系统的，你通过字节码插桩搞过一些事情吗，那你用过Cglib吧，它的底层就是通过ASM字节码框架对字节码进行的一些列操作。
- **实战项目**：以实战项目的方式学习互联网大厂开发中应用到的技术，通过这样的实践方式把一些学习的技术应用起来，而不是单单的去背资料，但最终不知道该如何把这些技术内容综合起来使用。所以这里小傅哥以实战项目为主，推出：[大营销平台系统](https://bugstack.cn/md/project/big-market/big-market.html)、[OpenAi 大模型应用服务](https://bugstack.cn/md/project/chatgpt/chatgpt.html)、[Lottery 分布式抽奖系统](https://bugstack.cn/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.html)、[透视业务监控系统](https://bugstack.cn/md/zsxq/project/business-behavior-monitor.html)、[动态线程池组件](https://bugstack.cn/md/zsxq/project/dynamic-thread-pool.html)、[API网关](https://bugstack.cn/md/assembly/api-gateway/api-gateway.html)等众多项目。
- **关于**：除了技术学习以外，还有很多伙伴会经常问我一些关于学习、成长以及在职场中怎么活下去。所以我结合我自己在大厂互联网中的学习和成长经历，给读者伙伴写了不少此类的内容。如简历编写、招聘要求、技术资料、代码规范、评审晋升、薪资待遇、副业收入等等。这些内容可能很多会帮助你度过一个安定的职场生涯！

## 二、学习路线参考

可能有很大一部分处于开始成长阶段的码农伙伴，不太清楚自己要从哪里开始学习，哪怕手里有几个T的资料，也没有办法把这些内容吸收到大脑中。因此我把一些非常有必要学习的知识串连出一条学习路径，帮助处于不同阶段的伙伴找到学习方向，也可以把自己的技术水平和工资代码，都拉起来。🌶



- Java 面经手册：[https://download.csdn.net/download/Yao__Shun__Yu/14932325](https://download.csdn.net/download/Yao__Shun__Yu/14932325)
- 重学Java设计模式：[https://download.csdn.net/download/Yao__Shun__Yu/19265731](https://download.csdn.net/download/Yao__Shun__Yu/19265731)
- SpringBoot 中间件设计和开发：[https://juejin.cn/book/6940996508632219689](https://juejin.cn/book/6940996508632219689)
- 🔥Lottery Plus 大营销平台系 - DDD 分布式架构技术实践：[https://t.zsxq.com/199mpn9Lt](https://t.zsxq.com/199mpn9Lt)
- [更多项目](https://gaga.plus)

## 三、算法

- 地址：[Java 数据结构和算法](https://bugstack.cn/md/algorithm/data-structures/data-structures.html)
- 介绍：以Java源码为基础，结合使用场景，学习数据结构和算法。涵盖4类14种数据结构，包括：链表、数组、队列、堆栈、哈希表、堆、字典树、二分搜索树、平衡二叉树、2-3树、红黑树、并查集、图、布隆过滤器。

## 四、Java

### 1. Java 面经手册

- 地址：[Java 面经手册](https://bugstack.cn/md/java/interview/2020-07-28-%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8C%20%C2%B7%20%E5%BC%80%E7%AF%87%E3%80%8A%E9%9D%A2%E8%AF%95%E5%AE%98%E9%83%BD%E9%97%AE%E6%88%91%E5%95%A5%E3%80%8B.html)
- 介绍：全书共计5章29节，417页11.5万字，耗时4个月完成。涵盖数据结构、算法逻辑、并发编程、JVM以及简历和互联网大厂面试等内容。



[《Java 面经手册》](https://bugstack.cn/md/project/pdf/2021-01-26-Java%E9%9D%A2%E7%BB%8F%E6%89%8B%E5%86%8CPDF%E4%B8%8B%E8%BD%BD.html) 是一本以面试题为入口讲解 Java 核心技术的 PDF 书籍，书中内容也极力的向你证实`代码是对数学逻辑的具体实现`。*为什么这么说？* 当你仔细阅读书籍时，会发现这里有很多数学知识，包括：扰动函数、负载因子、拉链寻址、开放寻址、斐波那契（Fibonacci）散列法还有黄金分割点的使用等等。

编码只是在确定了研发设计后的具体实现，而设计的部分包括：数据结构、算法逻辑以及设计模式等，而这部分数据结构和算法逻辑在 Java 的核心 API 中体现的淋漓尽致。那么，也就解释了为什么这些内容成为了热点面试题，虽然可能我们都会觉得这样的面试像是造火箭。

### 2. 用Java实现JVM

- 地址：[用Java实现JVM](https://bugstack.cn/md/java/develop-jvm/2019-05-01-%E7%94%A8Java%E5%AE%9E%E7%8E%B0JVM%E7%AC%AC%E4%B8%80%E7%AB%A0%E3%80%8A%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E3%80%8B.html)
- 介绍：本专题按照《java虚拟机规范》、go语言版《自己动手写Java虚拟机》来实现自己的java版虚拟机。从而深入学习jvm的基础功能；搜索和解析class、字节码指令集、运行时数据区、虚拟机栈、栈桢、局部变量表、操作数栈、寄存器等是如何一步步将java代码运行起来的。

### 3. 基础技术

- 地址：[基础技术](https://bugstack.cn/md/java/core/2020-01-06-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5D%E5%92%8B%E5%98%9E%EF%BC%9F%E4%BD%A0%E7%9A%84IDEA%E8%BF%87%E6%9C%9F%E4%BA%86%E5%90%A7%EF%BC%81%E5%8A%A0%E4%B8%AAJar%E5%8C%85%E5%B0%B1%E7%A0%B4%E8%A7%A3%E4%BA%86%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.html)
- 介绍：讲解 JDK 新特性、JDK 和 CGLIB 反射、Byte 字节、技术扩展、常忽略的技术问题，帮研发同学更好的拉伸自己的技术栈学习。

## 五、Spring

### 1. Spring 手撸专栏

- 地址：[Spring 手撸专栏](https://bugstack.cn/md/spring/develop-spring/2021-05-16-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Spring%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.html)
- 介绍：在写了部分关于 `Spring核心源码` 的面经内容后，我决定要去手撸一个Spring了。为啥这么干呢？因为所有我想写的内容，都希望它是以理科思维理解为目的方式学会，而不是靠着硬背记住。而编写面经的过程中涉及到的每一篇Spring源码内容分析，在即使去掉部分非主流逻辑后，依然会显得非常庞大。



- 此专栏是一本以开发简化版Spring学习其原理和内核的知识内容，不仅是代码编写实现也更注重内容上的需求分析和方案设计，所以在学习的过程要结合这些内容一起来实践，并调试对应的代码。粉丝伙伴在阅读的过程中，**千万不要害怕在学习的过程中遇到问题，这些都是正常的！** 希望你可以一直坚持把这些内容事必躬亲、亲历亲为的学完，加油！

### 2. Mybatis 手撸专栏

- 地址：[Mybatis 手撸专栏](https://bugstack.cn/md/spring/develop-mybatis/2022-03-20-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%BC%80%E7%AF%87%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%8B%E5%86%99Mybatis%E8%83%BD%E7%BB%99%E4%BD%A0%E5%B8%A6%E6%9D%A5%E4%BB%80%E4%B9%88%EF%BC%9F.html)
- 介绍：像我们之前完成[手写 Spring](https://mp.weixin.qq.com/s/g7YdIe_FSrk-WE8nQRO3TA)一样，拆解功能、简化流程、渐进实现，让读者能够更容易的学习到最有价值的知识。



在手写的过程中学习 Mybatis 从解析、绑定、反射、缓存，到会话和事务操作，以及如何与 Spring 进行关联注册 Bean 对象，完成整合部分功能逻辑。通过这些内容的拆解实现，读者伙伴就可以非常清楚的知道这些核心功能都是如何实现的了，以后再阅读 Mybatis 源码也就知道从哪开始到哪结束了。

### 3. Spring Cloud

- 地址：[Spring Cloud](https://bugstack.cn/md/spring/spring-cloud/2019-10-31-Spring%20Cloud%E9%9B%B6%E3%80%8A%E6%80%BB%E6%9C%89%E4%B8%80%E5%81%8F%E6%A6%82%E8%BF%B0%E5%91%8A%E8%AF%89%E4%BD%A0SpringCloud%E6%98%AF%E4%BB%80%E4%B9%88%E3%80%8B.html)
- 介绍：以案例实践的方式讲解 Spring Cloud 中常用的技术内容，包括：Eureka注册中心、熔断、降级、限流、动态刷新配置、消息总线、zuul 网关路由等

### 4. 源码分析

- 地址：[源码分析](https://bugstack.cn/md/spring/source-code/2019-12-25-%5B%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%5DMybatis%E6%8E%A5%E5%8F%A3%E6%B2%A1%E6%9C%89%E5%AE%9E%E7%8E%B0%E7%B1%BB%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5.html)
- 介绍：拆解、分析、实践的方式进行源码学习，包括对 Mybatis 的分析和手写，这部分内容涵盖的非常广泛，可以让你非常清楚一个 ORM 框架是如何开发的以及怎么结合到 Spring 中，同时这部分内容还包括了 Quartz 定时任务全流程的分析，可以帮助你更好的理解任务的分层处理。

## 六、面向对象

### 1. 重学Java设计模式

- 地址：[重学Java设计模式](https://bugstack.cn/md/develop/design-pattern/2020-05-20-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E5%AE%9E%E6%88%98%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F%E3%80%8B.html)
- 视频：[https://www.bilibili.com/video/BV1D341177SV](https://www.bilibili.com/video/BV1D341177SV) - `与重学Java设计模式相对应，成体系录制`
- 介绍：本书是作者小傅哥，基于互联网真实案例编写的Java设计模式实践图书。全书以解决方案为核心，从实际开发业务中抽离出交易、营销、规则引擎、中间件、框架源码等22个真实场景，对设计模式进行全面、彻底的分析。帮助读者灵活地使用各种设计模式，从容应对复杂变化的业务需求，编写出易维护、可扩展的代码结构。

| 序号 | 类型         | 图稿                                                         | 业务场景                                             | 实现要点                                                     |
| ---- | ------------ | ------------------------------------------------------------ | ---------------------------------------------------- | ------------------------------------------------------------ |
| 1    | **工厂方法** |  | 多种类型商品不同接口，统一发奖服务搭建场景           | 定义一个创建对象的接口，让其子类自己决定实例化哪一个工厂类，工厂模式使其创建过程延迟到子类进行。 |
| 2    | **抽象工厂** |  | 替换Redis双集群升级，代理类抽象场景                  | 提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。 |
| 3    | **生成器**   |  | 各项装修物料组合套餐选配场景                         | 将一个复杂的构建与其表示相分离，使得同样的构建过程可以创建不同的表示。 |
| 4    | **原型**     |  | 上机考试多套试，每人题目和答案乱序排列场景           | 用原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象。 |
| 5    | **单例**     |  | 7种单例模式案例，Effective Java 作者推荐枚举单例模式 | 保证一个类仅有一个实例，并提供一个访问它的全局访问点。       |

- 图片引用：[https://refactoringguru.cn](https://refactoringguru.cn)
- 出版图书：[https://mp.weixin.qq.com/s/g9LYQEqzOeiYOpfG_5XFYg](https://mp.weixin.qq.com/s/g9LYQEqzOeiYOpfG_5XFYg)

### 2. DDD 专题

- 地址：[DDD 专题](https://bugstack.cn/md/develop/framework/ddd/2019-10-15-DDD%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B%E4%B8%80%E3%80%8A%E5%88%9D%E8%AF%86%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1DDD%E8%90%BD%E5%9C%B0%E3%80%8B.html)
- 介绍：领取驱动设计DDD{Domain-Driven Design}历史较长但随着微服务的兴起DDD又活跃到人们的视线，它提供的是一套架构设计思想，我们可以使用这套方法论将架构设计的尽可能做到高内聚、低耦合、可扩展性强的应用服务。本专题以DDD实战落地为根本，分章节设计不同的架构模型。学习并实战是奔入应用级最快的方法，Hi HelloWorld！我来了。

### 3. 工程框架

- 地址：[工程框架](https://bugstack.cn/md/develop/framework/frame/2019-12-22-%E6%9E%B6%E6%9E%84%E6%A1%86%E6%9E%B6%E6%90%AD%E5%BB%BA%E4%B8%80%E3%80%8A%E5%8D%95%E4%BD%93%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E4%B9%8BSSM%E6%95%B4%E5%90%88%EF%BC%9ASpring4%20+%20SpringMvc%20+%20Mybatis%E3%80%8B.html)
- 介绍：讲解工程🏭框架的搭建，落地案例代码，方便有需要的研发伙伴以此为模板快速搭建自己需要的框架工程，也是一种入门的学习的最快方式。

### 4. 架构设计

- 地址：[架构设计](https://bugstack.cn/md/develop/framework/scheme/2021-02-04-%E5%9F%BA%E4%BA%8EIDEA%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E5%92%8C%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E6%8A%80%E6%9C%AF%EF%BC%8C%E5%AE%9E%E7%8E%B0%E7%A0%94%E5%8F%91%E4%BA%A4%E4%BB%98%E8%B4%A8%E9%87%8F%E8%87%AA%E5%8A%A8%E5%88%86%E6%9E%90.html)
- 介绍：讲解互联网大厂中一些场景的复杂场景，该如何设计和落地，包括：IDEA 插件、低代码、脚手架、DDD、中台、非入侵的全链路监控、字节码插庒等场景问题。

## 七、中间件

### 1. Spring Boot 中间件开发

- 地址：[Spring Boot 中间件开发](https://bugstack.cn/md/assembly/middleware/2019-12-02-SpringBoot%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86%E4%B8%AD%E9%97%B4%E4%BB%B6%E4%B9%8B%E7%BB%9F%E4%B8%80%E7%99%BD%E5%90%8D%E5%8D%95%E9%AA%8C%E8%AF%81.html)
- 介绍：讲解基础的 Spring Boot Starter 开发流程，以及如何设计实现的，并且该怎么把这样的插件发布到中心仓库中。如果对此感兴趣也可以阅读：[SpringBoot 中间件设计和开发](https://bugstack.cn/md/project/springboot-middleware/2021-03-31-%E3%80%8ASpringBoot%20%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91%E3%80%8B%E4%B8%93%E6%A0%8F%E5%B0%8F%E5%86%8C%E4%B8%8A%E7%BA%BF%E5%95%A6%EF%BC%81.html) - `这里有更完整的中间件开发学习，包括：服务治理、ORM框架、分布式组件、字节码应用`

### 2. IDEA Plugin 开发

- 地址：[IDEA Plugin 开发](https://bugstack.cn/md/assembly/idea-plugin/2021-08-27-%E6%8A%80%E6%9C%AF%E8%B0%83%E7%A0%94%EF%BC%8CIDEA%20%E6%8F%92%E4%BB%B6%E6%80%8E%E4%B9%88%E5%BC%80%E5%8F%91%EF%BC%9F.html)
- 介绍：IDEA 插件开发可以帮助研发人员提升能效，解决一些实际场景中的共性问题。但最近在折腾IDEA插件开发的时候，市面的资料确实不多，也没有成体系完整的开发指导手册，所以就遇到了很多不知道就不会的事情，需要一点点查询搜索源码、验证API接口，最终把各项功能实现，当然在这个过程中也确实踩了不少坑！接下来在这个专栏会把一些关于 IDEA 插件开发用到的各项知识做成案例输出出来，帮助有需要的研发伙伴，一起建设 IDEA Plugin



- **开发方式**：在官网的描述中，创建IDEA插件工程的方式有两种分别是，IntelliJ Platform Plugin 模版创建和 Gradle 构建方式。
- **框架入口**：一个 IDEA 插件开发完，要考虑把它嵌入到哪，比如是从 IDEA 窗体的 Edit、Tools 等进入配置还是把窗体嵌入到左、右工具条还是IDEA窗体下的对话框。
- **UI**：思考的是窗体需要用到什么语言开发，没错，用的就是 Swing、Awt 的技术能力。
- **API**：在 IDEA 插件开发中，一般都是围绕工程进行的，那么基本要从通过 IDEA 插件 JDK 开发能力中获取到工程信息、类信息、文件信息等。
- **外部功能**：这一个是用于把插件能力与外部系统结合，比如你是需要把拿到的接口上传到服务器，还是从远程下载文件等等。

### 3. API网关：中间件设计和实践

- 地址：[API网关：中间件设计和实践](https://bugstack.cn/md/assembly/api-gateway/2022-08-12-%E5%BC%80%E7%AF%87%EF%BC%9A%E5%A6%82%E6%9E%9C%E8%AE%A9%E6%88%91%E8%AE%BE%E8%AE%A1%E4%B8%80%E5%A5%97%EF%BC%8CTPS%E7%99%BE%E4%B8%87%E7%BA%A7API%E7%BD%91%E5%85%B3.html)
- 介绍：API网关，是所有互联网大厂都有的一个核心服务，承接着来自用户的滴滴打车、美团外卖、京东购物、微信支付，更是大促期间千万级访问量的核心系统。

## 八、Netty 4.x

- 地址：[Netty 4.x](https://bugstack.cn/md/netty/base/2019-07-30-netty%E6%A1%88%E4%BE%8B%EF%BC%8Cnetty4.1%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87%E9%9B%B6%E3%80%8A%E5%88%9D%E5%85%A5JavaIO%E4%B9%8B%E9%97%A8BIO%E3%80%81NIO%E3%80%81AIO%E5%AE%9E%E6%88%98%E7%BB%83%E4%B9%A0%E3%80%8B.html)
- 介绍：跟着案例学Netty，Netty4.x案例从简单入门到应用实战，全篇37章节优秀案例+实战源码[基础篇(13)、中级篇(13)、高级篇(3章+)、源码分析篇]，以上章节全部完成并不断持续更新中。

## 九、字节码编程(ASM、Javassist、Byte-Buddy)

- 地址：[字节码编程(ASM、Javassist、Byte-Buddy)](https://bugstack.cn/md/bytecode/asm/2020-03-25-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5D%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%8F%AA%E5%86%99CRUD%EF%BC%8C%E9%82%A3%E8%BF%99%E7%A7%8D%E6%8A%80%E6%9C%AF%E4%BD%A0%E6%B0%B8%E8%BF%9C%E7%A2%B0%E4%B8%8D%E5%88%B0.html)
- 介绍：但全书共计107页，11万7千字，20个章节涵盖三个字节码框架和JavaAgent使用并附带整套案例源码！讲道理，市面上以及网络搜索中都基本很少有成体系的关于字节码编程的知识，这主要由于大部分开发人员其实很少接触这部分内容，包括；ASM、Javassist、Byte-buddy以及JavaAgent，没有很大的市场也就没有很多的资料。但大家其实已经从其他的框架或者中间件中使用到，就像你用到的；Cglib、混沌工程、非入侵的全链路监控以及你是否使用过jetbrains-agent.jar做了某项实验？

## 十、实战项目

### 1. 业务类型

#### 1.1 大营销平台系统

项目：[https://bugstack.cn/md/project/big-market/big-market.html](https://bugstack.cn/md/project/big-market/big-market.html)

这个新项目，结合小傅哥已经带着大家完成的 OpenAi 大模型应用业务场景，做上层的营销活动。这就像互联网公司中有了电商、外卖、出行等场景一样，在场景之上做营销活动。所以我们的新项目是 **《大营销平台系统》**！因为小傅哥的星球之前做过了一个抽奖，那么这个项目会用新的DDD架构，对抽奖系统进行重构，并扩展出`营销账户`、`用户返利`、`积分兑换`等服务，完成一整套的营销平台功能。💥



#### 1.2 OpenAi 大模型应用服务体系构建 - API-SDK、鉴权、公众号、企业微信、支付服务

项目：[https://bugstack.cn/md/project/chatgpt/chatgpt.html](https://bugstack.cn/md/project/chatgpt/chatgpt.html)

此项目以围绕类似 ChatGPT 生成式服务，构建微服务应用架构体系组件。包括；用户鉴权、公众号、多方支付、企业微信等对接方式，满足不同诉求的使用。并以模块化设计，积木式构建应用，让不同的场景诉求都可以配置化对接。



#### 1.3 Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践

- 地址：[Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践](https://bugstack.cn/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.html)
- 介绍：`Lottery 抽奖系统` 项目是一款互联网面向C端人群营销活动类的抽奖系统，可以提供抽奖活动玩法策略的创建、参与、记账、发奖等逻辑功能。在使用的过程中运营人员通过创建概率类奖品的抽奖玩法，对用户进行拉新、促活、留存，通常这样的系统会用在电商、外卖、出行、公众号运营等各类场景中。



在此项目中你会学习到互联网公司关于C端项目开发时候用到的一些，技术、架构、规范等内容。由于项目为实战类编程项目，在学习的过程中需要上手操作，小傅哥会把系统的搭建拉不同的分支列为每一个章节进行设计和实现并记录到开发日记中，读者在学习的过程中可以结合这部分内容边看文章边写代码实践。

- 技术：SpringBoot、Mybatis、Dubbo、MQ、Redis、Mysql、ELK、分库分表、Otter
- 架构：DDD 领域驱动设计、充血模型、设计模式
- 规范：分支提交规范、代码编写规范

#### 1.4 IM Netty 仿PC端微信

- 地址：[IM Netty 仿PC端微信](https://bugstack.cn/md/project/im/2020-03-04-%E3%80%8ANetty+JavaFx%E5%AE%9E%E6%88%98%EF%BC%9A%E4%BB%BF%E6%A1%8C%E9%9D%A2%E7%89%88%E5%BE%AE%E4%BF%A1%E8%81%8A%E5%A4%A9%E3%80%8B.html)
- 介绍：🎭 本项目是作者小傅哥使用JavaFx、Netty4.x、SpringBoot、Mysql等技术栈和偏向于DDD领域驱动设计方式，搭建的仿桌面版微信实现通信核心功能。课程文章已发布到GitChat专栏，欢迎购买。

<div align="center">
    <img src="https://bugstack.cn/assets/images/2020/project.jpg?raw=true" width="900px">
    <img src="https://bugstack.cn/assets/images/2020/ui-01.png?raw=true" width="900px">
</div>

**第一章节**：**UI开发**。使用`JavaFx`与`Maven`搭建UI桌面工程，逐步讲解登录框体、聊天框体、对话框、好友栏等各项UI展示及操作事件。从而在这一章节中让Java 程序员学会开发桌面版应用。

**第二章节**：**架构设计**。在这一章节中我们会使用DDD领域驱动设计的四层模型结构与Netty结合使用，架构出合理的分层框架。同时还有相应库表功能的设计。相信这些内容学习后，你一定也可以假设出更好的框架。

**第三章节**：**功能实现**。这部分我们主要将通信中的各项功能逐步实现，包括；登录、添加好友、对话通知、消息发送、断线重连等各项功能。最终完成整个项目的开发，同时也可以让你从实践中学会技能。

### 2. 组件类型

#### 2.1 透视业务流程 - 监控系统

项目：[https://bugstack.cn/md/zsxq/project/business-behavior-monitor.html](https://bugstack.cn/md/zsxq/project/business-behavior-monitor.html)

本次项目会采用基于扩展 logback 日志上报数据进行 ognl 配置节点公式的方式进行采集、计算和可视化渲染。在这套项`小而美，小而精`的组件项目中，你可以学习到非常多的实战技能。

这套`透视业务流程的监控系统`，与 `Prometheus + Grafana`、`Skywalking` 有较大的差异。这两款监控都是系统健康度监控，而小傅哥带着大家做的是业务流程监控。*很多中大厂，也都有同类的业务系统*



#### 2.2 动态线程池组件实现

项目：[https://bugstack.cn/md/zsxq/project/dynamic-thread-pool.html](https://bugstack.cn/md/zsxq/project/dynamic-thread-pool.html)

本次带着大家做的这款动态线程池组件项目，也是各个中大厂中都非常常见的组件能力。通过这样的学习，以中大厂的经验补充自身的技术积累，让自己的简历和职业生涯都有东西可讲。

我们知道，线程池（Thread Pool），是一种基于池化思想管理线程的工具，用于降低资源消耗、提高响应速度、提高线程的管理性。池化技术的引入，可以有效的减少线程频繁申请/销毁和调度所带来的额外开销。对于池化思想，我们还能看到；内存池、连接池、化粪池。



#### 2.3 支付SDK设计和开发

项目：[https://bugstack.cn/md/zsxq/project/ltzf-sdk-java.html](https://bugstack.cn/md/zsxq/project/ltzf-sdk-java.html)

在面试中详细了解得知，不少伙伴压根是没有做支付的。而是一个假的模拟支付，修改数据库状态，当做支付而已。这样做有个很大的问题就是没法全面的了解支付流程，包括在`掉单`、`幂等`、`透传`、`回调`等方面的业务是很难清晰的理解的。所以在面试过程中也就压根不知道支付这一块。但不写支付，又觉得整个项目不完整，并且很多公司面试都会问一些支付的内容。那怎么办😰呢？

小傅哥在带着大家做的项目和小场景中，有做过微信支付，支付宝沙箱支付，但想做真实的支付一般是需要个体户或者公司主体的。不过好在市面还有一些专门提供给个人使用的支付，比如；蓝兔、虎皮椒、PayJS。这些支付中，小傅哥测试验证了蓝兔支付，为它提供了一款SDK，让大家像使用微信支付一样简单的使用蓝兔支付。



#### 2.4 《SpringBoot 中间件设计和开发》

- 地址：[《SpringBoot 中间件设计和开发》](https://bugstack.cn/md/project/springboot-middleware/2021-03-31-%E3%80%8ASpringBoot%20%E4%B8%AD%E9%97%B4%E4%BB%B6%E8%AE%BE%E8%AE%A1%E5%92%8C%E5%BC%80%E5%8F%91%E3%80%8B%E4%B8%93%E6%A0%8F%E5%B0%8F%E5%86%8C%E4%B8%8A%E7%BA%BF%E5%95%A6%EF%BC%81.html)
- 介绍：说到底，为什么要扒开CRUD的表面，深入到核心源码实践学一些中间件开发技能，还不是希望自己对技术栈学习有一定的深度，免得面试时被人忽悠压薪资。就像人家问你：类的代理、反射调用是在什么场景用到的？ 自定义注解是怎么和切面一起获取到信息使用的？你需要的yml配置信息是如何被SpringBoot加载并初始化的？Bean 是如何被注入到 Spring 容器，提供服务的？综上，等等这些技术点可能很多时候你所学到的只能称作为背答案、记结果，因为没有实操所以过后就忘而且也扛不住面试官的接连发问。



- **技术框架**：包括 Spring、SpringBoot 配置加载、自定义注解、扫描注册Bean等，以及 ORM 框架设计原理和实现。这部分技术主要是把开发的中间件与框架结合，开发相应的组件或者包装为各类 SpringBoot Starter 的能力学习。
- **数据服务**：Mysql、Redis、Elasticsearch，都是数据服务，通常需要开发各类组件对数据服务的使用进行封装，Mysql 我们知道有 JDBC，Redis 我们知道有 Jedis，但 Elasticsearch 有 x-pack 你是否了解。
- **数据组件**：这类组件的开发就是为了简化对数据服务的使用，Mysql+JDBC+ORM，可以非常方便的使用数据库服务，那么 Elasticsearch 是否也可以做相应的组件研发，让它的查询也能像使用 MyBatis 一样呢？二折页的技术能力就需要对 MyBatis 等 ORM 框架的实现原理熟悉，同时需要了解 JDBC 的概念。
- **分布式技术**：RPC 框架、注册中心、分布式任务，都是现有互联网分布式架构中非常重要的技术，而对于如何实现一个 RPC 框架，也技术是研发人员要掌握的重点，同时如何使用注册中心、怎么下发分布式调度任务，等等，这些技术的学习能让对现有的框架使用有更深入的认识。
- **服务治理**：熔断、降级、限流、切量、黑白名单以及对现有方法的非入侵式扩展增强等，都可以成为是服务治理类组件，原本这类技术在早期是与业务逻辑代码融合的，后来逐步被拆解出来，开发成对应的组件。所以我们可以学习到，关于这类组件的包装、集成是如何做的。
- **字节码&插件**：在互联网的系统应用运维过程中，你一定会接触到各类的监控系统，而很多监控系统是非入侵的全链路监控，那么这些是如何实现的呢？其实它们是基于字节码插桩，对系统方法的增强，采集相应的运行时信息，进行监控的。再到扩展 JVMTI、IDEA 插件开发，都是为了整个研发过程的可持续交付和上线提高交付质量和降低人效的。

#### 2.5 API网关

项目：[https://bugstack.cn/md/assembly/api-gateway/api-gateway.html](https://bugstack.cn/md/assembly/api-gateway/api-gateway.html)

API网关系统用于统一管理RPC（Dubbo）通信接口，通过协议解析和泛化调用统一对外提供HTTP服务的系统。这套系统是微服务架构设计，分为核心通信、启动引擎、注册中心、管理平台以及上报接口服务。这套API网关也是随着对公司传统庞大的单体应用（All in one）拆分为众多的微服务（Microservice）以后，所引入的统一通信管理系统。用于运行在外部HTTP请求与内部RPC服务之间的一个流量入口，实现对外部请求的协议转换、参数校验、鉴权、切量、熔断、限流、监控、风控等各类共性的通用服务。



这是一整套API网关的核心通信模型结构图，以API网关算力的多套服务注册到网关中心开始，拉取RPC应用接口并完成映射HTTP调用操作。最终允许用户通过 Nginx 访问和路径重写的负载均衡管理，调用到具体的网关算力中执行协议解析和RPC接口的泛化调用并最终返回结果数据。

**综上**，这些贯穿整个互联网系统架构中的各类典型中间件，都会在后续章节中陆续讲解出来，它们是如何设计和实现的，一点点带你解开中间件的神秘面纱，让你的技术栈知识也增加一些有深度的并且是可以亲自操作的内容。


## 📚PDF 下载

- Java 面经手册：[https://download.csdn.net/download/Yao__Shun__Yu/14932325](https://download.csdn.net/download/Yao__Shun__Yu/14932325)
- 重学Java设计模式：[https://download.csdn.net/download/Yao__Shun__Yu/19265731](https://download.csdn.net/download/Yao__Shun__Yu/19265731)
- 字节码编程：[https://download.csdn.net/download/Yao__Shun__Yu/12505051](https://download.csdn.net/download/Yao__Shun__Yu/12505051)
- IDEA Plugin 开发手册：[https://download.csdn.net/download/Yao__Shun__Yu/77484299](https://download.csdn.net/download/Yao__Shun__Yu/77484299)

## 关于

关于自己、关于学习、关于职场，👉 如果你是刚入行、在外包、跨语言学习、想跳槽大厂、缺少学习动力等，可以阅读小傅哥的成长故事，这个系列包括了我的个人在外包到大厂的成长、跳槽的过程、互联网的学习经历，那么可以阅读一下。Go -> [https://bugstack.cn/md/about/me/about-me.html](https://bugstack.cn/md/about/me/about-me.html)

---

### Md Other Road Map (`docs/md/other/road-map.md`)

---
title: 编程路书
---

# bugstack虫洞栈 | 编程路书 v1.0 👣 - Java 程序员的简明教程 👨🏻‍💻 @小傅哥

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/road-map-logo.png?raw=true">
</div>

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、前言：授业解惑

`我知道，你不知道的还有很多！`

你了解计算机要从哪里开始学习吗？你清楚为了能找到工作要学习多少知识吗？你知道承接需求到开发交付上线串联了多少个技术栈吗？

对于这些内容即使从事编程2-3年的研发，大部分人也没有一个全局的概括，而在校大学生更是不清楚自己是从哪开始要到哪里去。收集了几十G到几百G的资料也不知道要从哪开始看，看哪些是对自己当前阶段帮助最大的。

**所以**在这个22年的1024程序员👨🏻‍💻节，小傅哥编写了一版**Java 编程路书**，希望帮助到更多从事这一行业的伙伴，可以更好的了解都要学习哪些技术。并且小傅哥会不断地收集、整理、归纳出来优秀的硬核资料，帮助大家学习。

## 二、查阅：路书地图

- **地址**：[https://github.com/fuzhengwei/RoadMap](https://github.com/fuzhengwei/RoadMap) - 提供了路书仓库，我会在这里更新各项资料，你可以进入后，点击右上角 Star 进行收藏（这样我更新后你会收到通知）
- **介绍**：整个路书以需求承接到开发交付为视角，包括：计算机基础、系统和架构设计、环境搭建、系统开发、常用类库、调试、测试、质量分析、发布部署。通过这样的全局的视角，来告诉你在哪里，要去哪里。*点击各个技术栈可以直接进入内容*
- **说明**：**A**——核心技术，学习完能承担大部分工作、**B**——辅助路线，学习完能更好的完成工作。

---
<br/>

<RoadMap></RoadMap>

## 三、收藏：资料仓库

- **仓库**：[https://github.com/fuzhengwei/RoadMap](https://github.com/fuzhengwei/RoadMap)
- **介绍**：以编程路书为指导，小傅哥会不断的添加相关的技术内容。也欢迎小伙伴提交 PR/Issue 来完善资料。

<div align="center">
    <a href="https://github.com/fuzhengwei/RoadMap" target="_blank" style="color:black;text-decoration:none;">
        <img src="https://bugstack.cn/images/roadmap/road-map-github.png?raw=true" width="800px">
    </a>
</div>

---

### Md Road Map 13scan Jdumpspider (`docs/md/road-map/13scan-jdumpspider.md`)

---
title: w13scan-jdumpspider 安全漏洞扫描
lock: need
---

# 安全漏洞扫描，他怎么拿到了我的数据库密码？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

你有没有想过，你部署到线上的 SpringBoot 应用，在做互联网`安全人员`的手里，已经成了"小肉鸡"？可怕的攻击不一定是 DDOS 玩命的访问你的网站，消耗你的 CDN 流量。而是拿到你的应用系统的一系列配置，如；数据库账号密码和连接地址、微信公众平台核心配置、OpenAI APIKey。可以说这些东西一暴漏，那你得遭老罪喽。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-00.png" width="150px"/>
</div>

**那这是怎么被发现暴漏的呢？🤔**

做安全的有一套应用漏洞检查扫描的软件，它通过启动被动流量扫描服务，通过代理的方式，挂载到自身的浏览器。日常的访问一些网站时，所有的流量节点都会进入到被动扫描代理服务中，之后消耗这些流量节点，依次检测每个地址下可能发生的；XSS、jsonp信息泄露、sql注入、http smuggling 走私攻击，以及可以根据各类组件提供的漏洞问题做扫描补偿。这样就可以拿到你的网站都有哪些安全漏洞问题了。

这里有一个最典型的就是 SpringBoot Actuator 安全点暴漏，这东西是可以拿到你的 heapdump，之后再通过 JDumpSpider 扫描，也就可以拿到你应用中的数据源、配置文件、Redis配置、ShiroKey等信息。此时如果你的数据库恰好没有配置IP访问限制，那么直接远程连接登录进去，一顿操作了。

那么整个这样一个流程怎么玩一下呢？这东西只有亲自上下手，才会感受到它的恐怖。接下来，小傅哥就教你做被动安全扫描操作和 heapdump 下载分析提取数据库密码。

## 一、流程介绍

关于被动扫描系统安全漏洞的服务系统有很多，包括 w13scan 免费开源的，也有 xray 付费的，还有的是公司或者个人独立开发的。本节我们主要使用 w13scan 作为安全漏洞扫描的案例。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-01.png" width="500px"/>
</div>

- 首先， w13scan 的流程是这样，你需要先启动一个这样的被动扫描服务，之后再你的浏览器中配置网页请求代理地址。这个代理地址就是 w13scan 服务。
- 那么，这个时候你所有在浏览器发起的请求，都会经过 w13scan 走一圈。这样，就可以把请求的网址进行一系列安全扫描检查，查看是什么样的漏洞。
- 另外，w13scan 不只是可以被动扫描还可以主动配置路径扫描一个固定的网站地址检测。
- 最后，w13scan 会把扫描到的安全漏洞以html方式展示出来，我们可以在这个网页上查看漏洞检测结果。也就可以在进一步对存在的漏洞进行挖局，如拿到 heapdump 在解析它的信息了。

## 二、案例工程

这里小傅哥为你提供了完整的案例测试工程，你可以直接完整体验。`你需要有 docker 环境或者 Python 3.6+`

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-02.png" width="750px"/>
</div>

地址：[https://github.com/fuzhengwei/xfg-dev-tech-w13scan-jdumpspider](https://github.com/fuzhengwei/xfg-dev-tech-w13scan-jdumpspider)

- 首先，你需要下载这个工程到本地电脑，便于安装环境和测试。
- 如图，已经为你描述了案例的功能。

## 三、被动扫描

**源码**：[https://github.com/fuzhengwei/w13scan](https://github.com/fuzhengwei/w13scan) - 小傅哥 fork 的 w13scan 并做了镜像打包。源码文档里提供了安装和使用说明。

### 1. 组件安装 - docker 方式

```java
# docker-compose -f docker-compose.yml up -d
version: '3.8'
services:
  w13scan:
    image: fuzhengwei/w13scan:1.0
    container_name: w13scan
    ports:
      - "7778:7778"
    volumes:
      - ./output:/w13scan/W13SCAN/output
    entrypoint: ["python3", "w13scan.py", "-s", "0.0.0.0:7778", "--html"]
    tty: true
```

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-03.png" width="750px"/>
</div>

- 你可以通过脚本 `docker-compose -f docker-compose.yml up -d` 脚本执行 w13scan 的服务安装。
- 另外，如果你不能执行 docker-compose 还可以通过提供的 `docker run -d --name w13scan -p 7778:7778 -v ./output:/w13scan/w13scan/output fuzhengwei/w13scan:1.0 python3 w13scan.py -s 127.0.0.1:7778 --html`

### 2. 组件安装 - Python 方式

这个方式就把代码拉到自己本地，进行构建和启动。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-04.png" width="750px"/>
</div>

```java
git clone https://github.com/fuzhengwei/w13scan.git
cd w13scan # 进入git目录
pip3 install -r requirements.txt
cd W13SCAN # 进入源码目录
python3 w13scan.py -h
```

```java
python3 w13scan.py -s 127.0.0.1:7778 --html # 端口可省略，默认为7778,开启--html即实时生成html报告
```

- 安装完成后启动，也可以看到一个 ` HTTPServer is running at address('0.0.0.0','7778')......` 日志。

### 3. 代理配置

无论使用那种方式部署，启动完成后，都需要给浏览器配置代理。其实也就是你的电脑的网络哪里配置下代理。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-05.png" width="750px"/>
</div>

- 给你的网络配置代理服务，我这里是 mac 电脑点网络wifi那里进入的配置。你可以找到你的位置进行添加。

### 4. 下载证书

下载：[http://w13scan.ca/](http://w13scan.ca/)

一定是你服务启动成功，代理配置成功。那么你在点击下载后，才能下载一个 `download.crt` 文件。之后双击点开信任即可。

### 5. 开始使用

一切配置成功后，你可以在浏览器访问你想检查漏洞的网址，一段时间后就可以看到被动扫描组件检测的数据信息了。之后进入到 `w13scan/W13SCAN/output` 查看检测文件了。这些 html 文件直接用浏览器打开和刷新即可。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-06.png" width="750px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-09.png" width="750px"/>
</div>

- 现在你就看到一些展示的系统安全漏洞了，再根据这些漏洞进行**友好的访问**

## 四、heapdump 下载

测试前你可以先启动 xfg-dev-tech-w13scan-jdumpspider 应用。这样就可以做后面的流程以及获取 heapdump 日志了。

### 1. 问题背景

测试工程中的 yml 配置。这个配置为了配合普罗米修斯做监控使用的，但要注意如果只是这样配置，是很有风险的。

```java
# 监控
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true
  prometheus:
    enabled: true
```

- 如果你的 SpringBoot 系统配置了这样的监控，并且没有配置相关的安全校验，Spring Security 那么现在你就暴漏了自己的端点。

### 2. 端点访问

地址：[http://127.0.0.1:8091/actuator/env](http://127.0.0.1:8091/actuator/env)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-07.png" width="550px"/>
</div>

- 这个地址，就可以由被动扫描检测出来。不过不同的被动扫描组件检测点不同，有些是没有的。

### 3. 下载 dump

地址：[http://127.0.0.1:8091/actuator/heapdump](http://127.0.0.1:8091/actuator/heapdump)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-w13scan-jdumpspider-08.png" width="250px"/>
</div>

- 把工程的 heapdump 文件下载下来。下载后可以放到案例工程 docs 里 JDumpSpider-1.1-SNAPSHOT-full.jar 的同层路径下。

## 五、heapdump 解析

以前小傅哥带着大家做一篇[《Eclipse MAT 分析 Java heap space dump 日志》](https://bugstack.cn/md/road-map/dump-mat.html) 这个也能分析 dump 日志查看系统中的核心数据。不过这里我们选择个更针对性的 JDumpSpider 做日志分析，直接提取核心配置。

源码：[https://github.com/whwlsfb/JDumpSpider](https://github.com/whwlsfb/JDumpSpider) - 有相关的使用说明。

命令：`java -jar JDumpSpider-1.1-SNAPSHOT-full.jar heapdump`

```java
/bin/zsh /xiaofuge/develop/github/xfg-dev-tech-w13scan-jdumpspider/docs/jdumpspider.sh
(base) xiaofuge@ZBMac-GV47H1GXD docs % /bin/zsh /Users/xiaofuge/Documents/develop/github/xfg-dev-tech-w13scan-jdumpspider/docs/jdumpspider.sh
===========================================
SpringDataSourceProperties
-------------
password = 123456
driverClassName = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://127.0.0.1:13306/road_map?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC&useSSL=true
username = root

===========================================
WeblogicDataSourceConnectionPoolConfig
-------------
not found!

===========================================
MongoClient
-------------
not found!

===========================================
AliDruidDataSourceWrapper
-------------
not found!

===========================================
HikariDataSource
-------------
not found!
```

- 命令执行后可以看到你的工程中连接数据库的配置，密码也会直接暴漏出来。其他的配置如果你有添加，也会一并给你拿出来。**底裤给你扒掉**

## 六、安全建议

- 对于自己上线的应用，尤其独立开发者，一定多进行安全扫描。
- 不要无密码暴漏自己的应用，包括任何监控、数据采集、以及第三方组件。
- 数据库、缓存、文件等连接，在云服务器要配置上可访问IP限制。这样就算底裤拔掉了，也还有一个玻璃罩。只能看，不能连。

---

### Md Road Map 1panel (`docs/md/road-map/1panel.md`)

---
title: 1Panel 运维面板
lock: need
---

# 1Panel 云服务器运维面板 | 操作云服务器，这套东西还适合小白的！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

在编程的这条路上，大家都经历过小白阶段。在小白阶段，即使是简简单单的环境安装，也都会遇到一堆堆的报错。所以最开始学习编程的时候，我们都希望找到那些简单、方便、好用的工具，让我们线上手✋🏻。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/springcloud-gateway-01.gif" width="200px"/>
</div>

**那云服务器操作有Easy工具吗？🤔**

小傅哥，在最早使用云服务器的时候，为了快速简单的搭建博客对外使用，选择过宝塔面板。这个东西虽然不大，但对于最开始云服务器操作能力和对编程的理解都比较偏弱的伙伴还是非常好用的。

但当大家开始使用 Linux + Docker，对一些列分布式环境继续安装和项目构建部署时，有些小白就会遇到一些各类小问题了。只有写好了 docker compose 和对应的文档，才能让小白快速完成安装。但有一些小白用到的新的服务安装时，自己不会写 docker compose 就会遇到新问题了。所以，今天我们来体验下一个新的云服务器运维面板，非常好用。

## 一、面板介绍

1Panel 是新一代的 Linux 服务器运维管理面板，它可以帮助你非常方便管理云服务器上的软件操作。`也不需要再配置 docker 代理了。`

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-1panel-01.png" width="950px"/>
</div>

- 用户可以通过 Web 图形界面轻松管理 Linux 服务器，实现主机监控、文件管理、数据库管理、容器管理等功能。
- 深度集成开源建站软件 WordPress 和 Halo，域名绑定、SSL 证书配置等一键搞定。
- 精选上架各类高质量的开源工具和应用软件，协助用户轻松安装并升级。
- 基于容器管理并部署应用，实现最小的漏洞暴露面，同时提供病毒防护、防火墙和日志审计等功能。
- 支持一键备份和恢复，用户可以将数据备份到各类云端存储介质，永不丢失。

> 好啦，介绍的还挺🐂皮的，咱们来体验下！

## 二、安装软件

### 1. 安装脚本

```java
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
```

- Centos 一键安装脚本，复制到云服务器直接执行即可。
- 其他的云服务器系统安装脚本：https://1panel.cn/docs/installation/online_installation/
- 2c2g 云服务器，活动价，一年26元 [https://618.gaga.plus](https://618.gaga.plus)

### 2. 安装效果

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-1panel-02.png" width="950px"/>
</div>

- 安装过程中你可以顺序点回车即可，注意是否配置镜像加速，因为我配置过，所以没有配置。你可以选 Y 统一配置镜像加速。
- 安装完成后，会得到一个外网地址，端口是默认的 19166，同时给会你用户和密码。注意，需要在云服务器开放端口（安全组/防火墙）19166 另外账号密码可以在登录后修改。

## 三、软件功能

### 1. 查看容器

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-1panel-03.png" width="950px"/>
</div>

- 你的 Linux 安装 Docker 会直接被 1Panel 接管。在 1Panel 会看到你安装过的软件。
- 同时可以看到每个软件占用的 CPU、内存，这个还是非常好用的。

### 2. 安装软件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-1panel-04.png" width="950px"/>
</div>

- 在 1Panel 的应用商店里，可以按照你需要的各类软件（它的覆盖度还是非常全的），包括常用的：Nginx、MySQL、MQ、Nacos、PHPAdmin等等，都是有的。
- 如图，是个 OneAPI 它是用于访问兼容访问各类其他 OpenAI 的软件的。比如，文心一言、通义千问、讯飞星火、智谱 ChatGLM、腾讯混元，都可以按照 ChatGPT 的格式进行使用啦。

>好啦，你可以美滋滋的去体验下啦！🌶

---

### Md Road Map A2a (`docs/md/road-map/a2a.md`)

---
title: a2a
lock: need
---

# A2A，实际跑起来是什么样？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=116247031185424&bvid=BV1QTwfzzEcu&cid=36776771626&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

chatgpt（22年）-> LLM 进阶（23年）->  MCP 协议（24年）-> Skils 技能（25年）-> A2A 标准（25年），这几年 AI 发展的非常迅速，定义了协议，开发了组件，发布了产品。每个阶段，都有非常牛皮的代表性的内容，车速非常快🚌，不知道在坐的各位有没有掉队。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-01.gif" width="150px">
</div>

针对这些 LLM 大模型的相关知识，小傅哥也分别提供了相关实战类项目，包括；**AI 问答助手（23年）**、**OpenAi(ChatGPT/ChatGLM) 微服务应用体系构（23年）**、**OpenAI 代码自动评审组件（24年）**、**AI Agent 智能体 - 拖拉拽（25年）**、**AI MCP Gateway 网关服务系统（25年）**、**AI Agent 脚手架 + 场景应用（26年）**，通过这些实战项目，实践各类标准协议和技术组件（spring ai、google adk...）的使用，以及提供非常出色的解决方案。

因为后续的 ai agent 智能体项目，还会涉及到 a2a 协议，所以先给大家做个相关技术的使用方便大家快速实践理解。

>🧧 文末提供了20个实战项目（6个AI、5个业务、8个组件、1套源码），以及各类编程技术小册等。欢迎一起加入学习。

## 一、A2A 是什么？

A2A (Agent2Agent) 协议是 Google于2025年4月推出、并由 Linux基金会托管的开源开放标准。它作为AI智能体之间的“通用语言”，旨在实现不同框架、不同厂商构建的智能体（Agent）间跨平台发现、通信与协作。

随后25年底，Google 发布了 [a2a adk](https://central.sonatype.com/artifact/com.google.adk/google-adk-a2a/0.4.0) 组件（迭代速度很快）。之后借助代理开发工具包 (Google ADK)，我们可以构建复杂的多代理系统，其中不同的代理需要使用代理对代理 (A2A) 协议进行协作和交互！本节提供了一个全面的指南，指导您构建强大的多代理系统，使代理能够安全高效地进行通信和协作。

框架：[https://google.github.io/adk-docs/a2a/](https://google.github.io/adk-docs/a2a/)

源码：[https://github.com/google/adk-java](https://github.com/google/adk-java)

资料：[https://www.ibm.com/cn-zh/think/topics/agent2agent-protocol](https://www.ibm.com/cn-zh/think/topics/agent2agent-protocol)

文档：[https://a2aprotocol.ai/docs/](https://a2aprotocol.ai/docs/)

---

如图，整套智能体架构（含A2A）；

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-agent-scaffold/part-1/1-1/images/ai-agent-scaffold-1-1-02.png" width="950px">
</div>

- 左侧，是 LLM 模型智能体构建，基于 Spring AI 框架实现。这部分包括，AiApi 使用、RAG、MCP、Skills 的组合构建。
- 右侧，是 AI Agent 智能体编排，基于 Google ADK 框架实现。这套框架，提供了智能体工作流组装，插件回调钩子等各项基于 Google 发布的协议进行构建的。
- 之后，右上方，是 Google ADK 26年基于 A2A 协议实现的框架组件，方便我们设计出远程的 A2A 服务对接，把远程服务，转换为本地功能组件，编排进智能体中。因此 A2A 协议的作用，就是让一个远程的智能体，可以像构建本地智能体一样，连接起来进行使用。

> 基于 a2a  的协议，也有很多三方框架，但我们需要的是一个整体的解决方案，单一一个功能，还不能解决所有问题。所以这里优先选择 google adk 框架。

## 二、实践案例

### 1. 编程环境

- jdk 17
- google adk 0.8
- spring ai 1.1.0-M3

>相关的版本包，已经在测试工程中的 pom 里引入了。可以打开工程查看。

### 2. 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-02.png" width="550px">
</div>

- 工程：[https://github.com/fuzhengwei/xfg-dev-tech-google-adk-a2a-server](https://github.com/fuzhengwei/xfg-dev-tech-google-adk-a2a-server)
- 说明：基于 Google ADK 框架，构建 A2A 服务端和客户端。注意，服务端的启动方式为 `quarkus.sh` 方式启动服务，之后使用客户端连接。
- 注意：这部分还有一些关于关于 Spring AI + Google ADK 的基础使用知识，是在 ApiTest 中有案例。也可以学习项目 [《AI Agent 脚手架 + 场景应用》](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html)

### 3. 测试案例

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 这是一个 Spring AI + Google ADK 构建的简单智能体，由 LlmAgent 构建时候，创建模型 `new SpringAI(chatModel)` 关联到 Spring AI 框架。
- 之后，由 Google ADK 构建的智能体，使用内存记忆，创建会话之后进行测试。也可以学习项目 [《AI Agent 脚手架 + 场景应用》](https://bugstack.cn/md/project/ai-agent-scaffold/ai-agent-scaffold.html) 锻炼使用相关内容。

### 4. A2A 测试

#### 4.1 服务端

这部分内容的学习，可以打开案例代码，方便对比。

##### 4.1.1 服务提供

```java
@ApplicationScoped
public class AgentExecutorProducer {

    @ConfigProperty(name = "my.adk.app.name", defaultValue = "default-app")
    String appName;

    @Produces
    public AgentExecutor agentExecutor() {
        return new com.google.adk.a2a.executor.AgentExecutor.Builder()
                .agent(Agent.ROOT_AGENT)
                .appName(appName)
                .sessionService(new InMemorySessionService())
                .artifactService(new InMemoryArtifactService())
                .agentExecutorConfig(AgentExecutorConfig.builder().build())
                .build();
    }
    
}
```

- 这部分是把智能体提供出去，通过 google adk 框架，创建 AgentExecutor 实例。
- 之后 Agent.ROOT_AGENT 类似于上面的测试案例，智能体构建的部分。你可以创建任何之后通过 AgentExecutor 发布出去。

##### 4.1.2 卡片提供

```java
@ApplicationScoped
public class AgentCardProducer {

    @Produces
    @PublicAgentCard
    public AgentCard agentCard() {
        try (InputStream is = getClass().getResourceAsStream("/agent/agent.json")) {
            if (is == null) {
                throw new RuntimeException("agent.json not found in resources");
            }

            // Read the JSON file content
            String json = new String(is.readAllBytes(), StandardCharsets.UTF_8);

            // Use the SDK's built-in mapper to convert JSON string to AgentCard record
            return Utils.OBJECT_MAPPER.readValue(json, AgentCard.class);

        } catch (Exception e) {
            throw new RuntimeException("Failed to load AgentCard from JSON", e);
        }
    }

}
```

**/agent/agent.json**

```java
{
  "capabilities": {"streaming": true},
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["application/json"],
  "description": "一个专门检查数字是否为素数的智能体。它可以高效地确定单个数字或数字列表的素性。",
  "name": "check_prime_agent",
  "skills": [
    {
      "id": "prime_checking",
      "name": "Prime Number Checking",
      "description": "使用高效的数学算法检查列表中的数字是否为素数",
      "tags": ["mathematical", "computation", "prime", "numbers"]
    }
  ],
  "preferredTransport": "JSONRPC",
  "url": "http://localhost:9090",
  "version": "1.0.0"
}

```

- 这里要构建一个智能体卡，A2A 的协议中，把服务包装成一个卡片的概念。
- agent.json 配置的是 `Agent.ROOT_AGENT` 智能体的信息。
- 如果你之前学习过小傅哥的 AI MCP 网关项目，会对 JSONRPC 有印象， MCP 协议和 A2A 协议，都是走到 JSONRPC 标准进行的通信。

#### 4.2 客户端

##### 4.2.1 构建端

```
/* Detailed source-code truncated for AI context efficiency. */
```

- createRootAgent 是构建入口，一个是创建 createRemoteAgent 远程智能体，一个是 `LlmAgent.builder()` 构建本地智能体。之后在构建本地智能体的时候，通过 subAgents 把远程智能体填充到本地的智能体里去了。这个编排的方式有多种多样的。
- createRemoteAgent 远程构建，这是固定协议路径 `/.well-known/agent-card.json`拿到智能体卡片以后（一个卡片上有各类的信息），之后通过 a2aClient 创建客户端，在通过 RemoteA2AAgent 完成本地智能体的转换。

##### 4.2.2 使用端

```java
public final class A2AAgentRun {
    private final String userId;
    private final String sessionId;
    private final Runner runner;

    public A2AAgentRun(BaseAgent agent) {
        this.userId = "test_user";
        String appName = "A2AAgentApp";
        this.sessionId = UUID.randomUUID().toString();

        InMemoryArtifactService artifactService = new InMemoryArtifactService();
        InMemorySessionService sessionService = new InMemorySessionService();
        this.runner =
                new Runner(agent, appName, artifactService, sessionService, /* memoryService= */ null);

        ConcurrentMap<String, Object> initialState = new ConcurrentHashMap<>();
        var unused =
                sessionService.createSession(appName, userId, initialState, sessionId).blockingGet();
    }
    
    // ... 省略部分

    public static void main(String[] args) throws InterruptedException {
        BaseAgent agent = A2AAgent.createRootAgent("http://localhost:9090");
        A2AAgentRun a2aRun = new A2AAgentRun(agent);

        List<Event> events =
                a2aRun.run("掷一个6面的骰子。").toList().timeout(90, TimeUnit.SECONDS).blockingGet();

        events.forEach(A2AAgentRun::printOutEvent);

        events =
                a2aRun.run("这是素数吗？").toList().timeout(90, TimeUnit.SECONDS).blockingGet();

        events.forEach(A2AAgentRun::printOutEvent);
    }

}
```

- A2AAgentRun 测试入口，连接远程的智能体，之后做相关的调用验证。

## 三、测试验证

### 1. 前置准备

1. IntelliJ IDEA 右侧的 maven 点击执行 clean -> install 构建
2. 通过命令启动服务，`mvn quarkus:dev -pl xfg-dev-tech-app`

### 2. 访问服务

#### 2.1 服务首页

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-03.png" width="650px">
</div>

- 地址：[http://localhost:9090/q/dev-ui/welcome](http://localhost:9090/q/dev-ui/welcome)
- 说明：访问首页，localhost:9090 会看到上面的地址信息，这个是 a2a 协议的入口。

#### 2.2 服务协议

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-04.png" width="650px">
</div>

- 地址：[http://localhost:9090/.well-known/agent-card.json](http://localhost:9090/.well-known/agent-card.json)
- 说明：点击 agent-card.json 可以看到具体的服务协议信息。

### 3. 调用验证

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-a2a-05.png" width="850px">
</div>

- 点击运行，你可以看到它在进行多个智能体的调用（可能模型原因不准，但核心点在于多个智能体的调用）。
- 好啦，到这关于 A2A 整个内容就演示完了，可以时刻关注 google adk a2a 协议的迭代，这部分内容后续还会有一些调整。

---

### Md Road Map Agent Skill (`docs/md/road-map/agent-skill.md`)

---
title: agent-skills
lock: need
---

# Agent Skill，你记一下，我做如下部署调整！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115890381129183&bvid=BV1PprJBeEmY&cid=35370763226&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

skill 是什么？它像是一本技能书📚，把一阳指（`mcp/py/shell/js`）和狮吼功（`prompt`）合成了一整招。缩短了从用户把提示词发给AI客户端，进行分析，决策，再到 mcp 执行的过程，**让诉求直达结果**，token 减少了，幻觉减少了！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-00.png" width="250px">
</div>

随着 LLM 大模型能力的不断提升，并与 RAG、MCP、Skill 的结合，使得 Agent 智能体与完整的计算机环境（Computer/Phone）交互成为可能。这个过程中，一方面不断产生新的技术方案，一方面又不断的优化设计。就像 Skill 的出现，它不是替代 MCP，而是更准确的使用 MCP 能力。

接下来，小傅哥就带着大家使用一波 skill，让小伙伴们可以在 opencode、trae.ai，以及基于 Spring AI 也可以使用上 skill 能力。

## 一、skill 和 prompt + mcp

如图，演示了一段 skill 的编写案例；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-02.png" width="850px">
</div>

- 场景：案例中体现的是，对电脑性能检测后，用一段下达命令的方式，告知用户如何优化电脑性能。
- 重点：如果不使用 skill，则需要描述一大段话术，让 ai 自己完成对用户场景诉求的分析，并按照步骤来调用对应的各个 mcp 服务（没有 skill 则需要把各类内容，都包装为 mcp 服务）。这个过程是比较消耗 token 的，也可能有不小的幻觉。现在有了 skill，我们可以适当的完整的写一段诉求文档，文档里嵌入可执行的脚本/mcp服务，让执行更可靠。
- 用途：那都有哪些场景可以写 skill 技能书呢？🤔 如；互联网公司里的系统巡检，在接收到报警日志后，拿到一个报警的系统和接口信息，之后用 skill 技能书，分别采集出对应的系统配置、上线日志、数据库/缓存情况、运营操作记录、全链路监控上的接口耗时情况等。之后在根据我们日常排查问题的时候经验，编写过程步骤，这样会更加准确。

> 所以，不是 skill、mcp 谁替代谁，而是 skill 对 mcp 进行增强，让 ai 执行时更加可靠。

## 二、配置使用

首先，像是市面上的 claude code、opencode 这些软件，都是支持了 skill 技能书配置使用的，如果遇到一些软件暂时还不支持 skill，或者自己使用 spring ai、langchain4j、google adk 构建的智能体时候需要使用 skil 技能，则可以通过 skillport-mcp 来使用 skill 配置。

这里小傅哥分别演示下 opencode、trae.ai + mcp、spring ai + google adk + mcp 的方式使用 skill；

### 1. 测试工程(skill)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-03.png" width="300px">
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-agent-skills](https://github.com/fuzhengwei/xfg-dev-tech-agent-skills)
- 说明：
  - 工程里 `docs/skills` 下面就是一个个技能书，battle-plan、pdf，每一个技能书下都必须有一个 SKILL.md 文件，作为入口。这个文件，可以描述 prompt 提示词，以及在提示词中明确给出可执行的脚本(py\shell\js)和可参考的文档。
  - 此外，在 xfg-dev-tech-app 下，test 里编码的是 SpringAiToolTest 测试技能书案例。

### 2. opencode 使用

- 文档：[https://opencode.ai/docs/skills/](https://opencode.ai/docs/skills/)
- 安装：[https://bugstack.cn/md/road-map/ai-ssh-opencode.html](https://bugstack.cn/md/road-map/ai-ssh-opencode.html) - `做好了安装脚本，方便小白伙伴使用`

#### 2.1 配置skill

```java
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % ls
battle-plan
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % pwd
/Users/fuzhengwei/.opencode/skill
fuzhengwei@fuzhengweideMacBook-Pro-2 skill % cd battle-plan 
fuzhengwei@fuzhengweideMacBook-Pro-2 battle-plan % ls
reference.md	scripts		SKILL.md
fuzhengwei@fuzhengweideMacBook-Pro-2 battle-plan % 
```

进入到 opencode 配置文件下，如果是 linux 一般会放到 `/root/.config/opencode/` 下。首先你要进入到这个 opencode 配置文件夹，之后在这个文件夹添加一个 skill，再之后就在 skill 下创建你的具体的技能书了。现在你可以把 xfg-dev-tech-agent-skills 案例工程的技能书，battle-plan 放到 skill 里。

#### 2.2 开启skill

```java
fuzhengwei@fuzhengweideMacBook-Pro-2 ~ % cd /Users/fuzhengwei/.opencode
fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % ls
bin		node_modules	package.json
bun.lock	opencode.json	skill
fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % cat opencode.json 
{
  "permission": {
    "skill": {
      "pr-review": "allow",
      "internal-*": "deny",
      "experimental-*": "ask",
      "*": "allow"
    }
  },
  "$schema": "https://opencode.ai/config.json"
}%                                                                                            fuzhengwei@fuzhengweideMacBook-Pro-2 .opencode % 
```

- 注意 `opencode.json` 需要配置下 `"*": "allow"`

#### 2.3 使用skill

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-04.png" width="600px">
</div>

- 提问：`基于 skill 解答，电脑性能优化`
- 说明：这里的`电脑性能优化`就是 skill 工具名称的描述。

### 3. trae.ai + mcp + skill

#### 3.1 工具说明

工具：[https://github.com/gotalab/skillport](https://github.com/gotalab/skillport)

目前还有不少 AI Agent 智能体，在底层设计上，还不支持直接使用 skill，也包括一些 ai 组件框架，也都没有 skill 的直接支持。那么这里要引入一个 skillport-mcp 服务来解决。借助 mcp 能力，使用 skill。

#### 3.2 工具安装

```java
# 需要安装 python3
pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple/
pip3 install uvx
```

- 安装 skillport 前，要确保本地安装了 pyhton/python3 环境。之后有 uvx 的安装。

```java
pip3 install skillport
# or: uv tool install skillport
```

- 如果安装过程中遇到一些失败的问题，可以用 trae.ai 里面执行安装，之后把报错拖进去提问。

#### 3.3 mcp 配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-05.png" width="600px">
</div>

```java
{
  "mcpServers": {
    "skillport": {
      "command": "uvx",
      "args": ["skillport-mcp"],
      "env": { "SKILLPORT_SKILLS_DIR": "~/.skillport/skills" }
    }
  }
}
```

- 这里你要配置下自己 skill mcp 服务，到你的 trae.ai 中。确保一定安装好了 python 环境，可以执行 `pip3 install skillport` 安装。

#### 3.4 工具使用

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-agent-skill-01.png" width="400px">
</div>

当你选择 Builder with MCP（涵盖了skillport-mcp），之后提问 `基于 skill 解答，电脑性能优化` 那么就可以得到上面的命令了。

### 4. spring ai + skill

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 在 Spring AI 程序中，添加 `skillport-mcp` 服务，之后在 ChatModel 模型里，使用 mcp 服务。
- 如果你正在开发一些 AI Agent，那么也可以把 `skillport-mcp`  配置进去使用。如小傅哥带着做 [AI Agent 智能体项目](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 你现在可以加进去更多的扩展操作了。

---

### Md Road Map Ai Ssh Opencode (`docs/md/road-map/ai-ssh-opencode.md`)

---
title: ai ssh opencode
lock: need
---

# ai ssh opencode 命令行工具

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115811243001489&bvid=BV1hciNB9EsE&cid=35087846352&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

天才般的发明，**ai ssh 命令行工具**，让 ai 的使用不只局限在 `ai 对话提问`、`ai idea 辅助编码`，也可以直接让操作系统具备 ai 能力。其实这才是我一直想要的东西！😄

<div align="center">
	<img src="https://bugstack.cn/images/article/project/chatgpt/openai-01.jpg" width="150px"/>
</div>

**ai 正在改变产品设计！**

2025年，是 ai agent 智能体爆发的一年，它所提效的接入方式可以分三层来看；

先是中间这一层，是 ai agent 接入服务和软件，像是大家使用的 trae.ai 或者小傅哥分享过的 [draw.io + ai](https://bugstack.cn/md/road-map/draw.io.html)，以及各个互联网公司用 ai 提效做的一些场景客服，系统巡检，日志分析等。

之后上面这一层，是从用户视角，模拟用户行为使用软件，而不是直接接入到软件api上。它使用的方式是 AutoGLM-Phone-9B 手机模型，以 ADB 或者无障碍模式，让手机可以接收用户指令，完成操作。如；`打开京东，搜索东北老式麻辣烫，加入购物车，以默认地址，进行支付购买。下单支付完成后，微信发给xxx告诉，她预计送达时间。` 如果感兴趣，可以基于这篇文章进行实践。[《手机 + agent，这是要掀桌子！》](https://bugstack.cn/md/algorithm/model/autoglm-phone-agent.html)

然后底下这一层，是从系统层面，不再依赖于直接对接某个软件，某个api，而是以系统层面直接操作软件，或者完成整个行为动作。如，在云服务器/本地，配置好 jdk、maven、docker 环境，之后帮我拉取 git clone xxx 仓库代码，本地完成 maven 构建和启动。以及在遇到问题时候，让 ai 直接检索并处理都是非常可以的。

好，那接下来，小傅哥给大家分享下，如何安装一个 ai ssh 工具（没有这个教程，很多人是安装不上的！）。

>🧧 文末提供了小傅哥所有编程实战项目获取方式，一次加入即可获得19个已完结的实战项目，也有非常多的 AI 类项目，一定要补充学习！

## 一、工具介绍

ai ssh 是命令行工具，可以安装到 Mac、Windows、Linux 上，以通过 terminal（终端）直接操作系统进行使用。它的场景也包括你打开的 IntelliJ IDEA 下面的 terminal 终端中使用，这样就天然的嵌入到了 IntelliJ IDEA 中了，非常方便。

目前这类的 ai ssh 命令行工具软件也非常多，包括；[opencode.ai](https://opencode.ai/)、[claude](https://claude.com/product/claude-code)、[openai codex](https://github.com/openai/codex)、[阿里千问 - qianwen code](https://github.com/QwenLM/qwen-code)，都出了对应的软件。

在整体体验后，效果还是都不错的，这里是 opencode 的终端使用截图；

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-01.png" width="650px"/>
</div>

- opencode 默认提供了一些免费模型，可以输入 `/models` 进行选择。
- 另外还可以通过配置文件，添加其他模型，如 claude 模型、openai 模型、小米模型等。

## 二、软件安装

以下软件安装，会需要用到 gcc、nodejs 20+ 版本，建议安装 Ubuntu 24 版本，可以不需要折腾系统环境。

### 1. 脚本说明

这软件好用是挺好用，但它的源都在 Github 上，很多伙伴在执行官网脚本 `curl -fsSL https://opencode.ai/install | bash` 是安装不上的。所以，小傅哥做了一个对应的脚本，方便大家更加简化的安装使用。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-02.png" width="350px"/>
</div>

- 脚本（gitcode）：[https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install)
- 脚本（github）：[https://github.com/fuzhengwei/xfg-dev-tech-docker-install](https://github.com/fuzhengwei/xfg-dev-tech-docker-install)

### 2. 脚本下载

```java
git clone https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install.git
```

- 你可以通过命令的方式把脚本拉取到本地电脑或者云服务器上。

### 3. 脚本授权

```java
find . -name "*.sh" -type f -exec chmod +x {} \;
```

- 全部授权

```java
chmod +x terminal.sh
```

- 指定授权

### 4. 执行安装

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-03.png" width="650px"/>
</div>

```java
./terminal.sh
```

- 执行安装时，选择1，opencode code，这个是比较推荐的。
- 无论是 Windows、Mac、Linux 都可以使用这个脚本进行安装，我已经做好了对应的脚本。
- 安装完成后，需要输入 `opencode` 之后 Enter（回车）进入到系统中。如果提示 opencode 不是有效的命令，可以检查是否安装过程中有个提示 `source .../bashrc` 可以自行执行刷新。

## 三、软件配置

### 1. 命令使用

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-04.png" width="650px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-05.png" width="650px"/>
</div>

- `/init` - 创建/更新 Agents.md"
- `/review` - 检查变化"
- `/new` - 创建新的会话"
- `/models` - 选择模型"
- `/agents` - 智能体方式"
- `/session` - 会话列表"
- `/status` - 查看状态"
- `/mcp` - 选择mcp服务"
- `/theme` - 选择主题"
- `/editor` - 编辑"
- `/connect` - 链接模型提供者"
- `/help` - 帮助"
- `/commands` - 命令"
- `/exit` - 调试模式"

> 这些可能会随着版本更新而调整，你可以依次尝试下。

### 2. 配置模型（自定义 - 可选）

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-06.png" width="350px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-07.png" width="650px"/>
</div>

```java
{
    "$schema": "https://opencode.ai/config.json",
    "provider": {
        "my-model-openai": {
            "npm": "@ai-sdk/openai-compatible",
            "name": "OpenAPI",
            "options": {
                "apiKey": "你的apikey",
                "baseURL": "https://你的baseURL/v1"
            },
            "models": {
                "gpt-4.1": {
                    "name": "gpt-4.1"
                }
            }
        },
        "my-model-glm": {
            "npm": "@ai-sdk/openai-compatible",
            "name": "GLMAPI",
            "options": {
                "apiKey": "你的apikey",
                "baseURL": "https://open.bigmodel.cn/api/paas/v4"
            },
            "models": {
                "glm-4.7": {
                    "name": "glm-4.7"
                }
            }
        }
    },
    "model": "my-model-openai/gpt-4.1"
}
```

- 如果你想自己更换下模型，比如使用 openai 的或则 claude 的，那么需要你在脚本下的 terminal/opencode.json 进行更换，之后执行 `./opencode.json.sh` 进行创建。
- 如果先执行了 ``./opencode.json.sh`` 之后想更换配置的模型，则可以通过 vim 命令，编辑 `/root/.config/opencode/opencode.json`
- 其他的还有一些像是 mcp 的配置，可以参考官网（避免调整了配置错），[https://opencode.ai/docs/mcp-servers/](https://opencode.ai/docs/mcp-servers/)


## 三、软件使用

### 1. Linux

#### 1.1 构建项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-08.png" width="650px"/>
</div>

#### 1.2 安装软件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-09.png" width="650px"/>
</div>

#### 1.3 巡检系统

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-10.png" width="650px"/>
</div>

#### 1.4 编写文件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-11.png" width="650px"/>
</div>

>通过命令操作云服务器是非常便捷的，尤其是很多小白伙伴，有了这个可以说是如小白虎添翼！打开思路，你可以在更多地方使用上，尤其哪些环境安装都困难的伙伴。

### 2. Mac/Windows + IntelliJ IDEA

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-12.png" width="650px"/>
</div>

- 在本地电脑，除了可以像 Linux 举例那种安装和检查各类软件，也可以直接在 IntelliJ IDEA 开启，之后管理你的项目。
- 尤其是很多伙伴，拿到一个项目，不知道里面都是什么，也不清楚脚本能干啥，那你都可以使用 opencode 帮你解决。

### 3. IPad Pro

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-opencode-13.png" width="450px"/>
</div>

虽然 IPad Pro 没啥开发类软件，但如果你使用的是云服务器、Nas等，这些软件里安装 opencode，那么你也可以在 IPad Pro 安装 [termius.com](https://termius.com/) SSH 工具，通过 SSH 工具操作部署了 opencode 的 Linux 系统。

现在日常出门，带着 IPad Pro 也是可以处理一些小的开发的维护的，非常方便。IPad Pro + Nas 嘎嘎舒服！

---

### Md Road Map Aigc (`docs/md/road-map/aigc.md`)

---
title: AiGC
lock: need
---

# 入局AiGC，分币没赚！咋整滴？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

AiGC 入局后，连更一周小说，分币不赚，还被催更`擦边小故事`！我把这当做，不是 AiGC 入局，而是跳河！如果有想做这个方向的，可以先冷静下，看看自己适合不。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-01.png" width="350px">
</div>

最近一段时间受不少 AiGC 类广告的影响，`文生图`、`文生视频`、`故事成片`，在家动动手就能赚钱。一个视频都几千、几万的点赞。

听起来做这个也挺简单，让 DeepSeek 生成口播故事，把故事放到 AiGC 软件（现在一堆），选择故事成片，在把视频上传到抖音、快手、头条，完活！**就是不赚钱！**

>本文会分享 AiGC 视频制作的过程和注意点。另外作为技术人员，我们可以自己部署一个文生视频的软件服务，以及了解相关的 API 技术，也为后续自己开发 AiGC 做积累。

## 选择一个赛道！下场！

首先，你可以想好一个创作的主题，如果有多个主题，可以分别投放到不同的软件平台，尽量先垂直一个系列更新，如果一直没有流量，后面可以干掉重新换主题来。

主题可以包括；`婆媳关系`、`中老年相亲`、`农村故事`、`鬼故事`、`好看的景色+音乐`、`儿童诗歌`，也就是你尽量要找一些高频有大量客群的场景，只要推荐到这样的人群标签下，视频的播放量还是很高的。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-03.png" width="450px">
</div>

但不要想着这样就能赚钱，如果只是试试水，基于 DeepSeek 生成关键信息的故事（主题、背景、人物、故事线），再把故事放到文生视频完成后上传即可。**但这样做好，基本属于徒劳！**

在我尝试推了几个鬼故事后，没有看到什么流量，这时候有个哥们加我，说我这样推没用的。我也好奇的去加了下关注，他是专门做鬼故事系列的，每个内容都很精良，而且属于 TM 鬼故事 + 擦边！还备注上（收徒）！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-02.png" width="450px">
</div>

所以，从这块开始，我发现要想让一个内容有较不错的流量，需要以下几点；

1. 故事主体框架是明确、不能纯用 DeepSeek 来写。故事可以基于一些比较火的小说来制造。看过越多小说的，做这方面越有优势。
2. 故事内容太干净了也没有人看，在 DeepSeek + 文生视频允许的范围内，你都可以“肆意”创作。
3. 如果你时间更多，也更想做好，那么要对生成的视频，逐帧剪辑，也可能要多生成几次来使用。并制造好吸引人的封面！
3. 长期主义，1~3，你可以都不用考虑。而是真的一点点来结合 AI 来写长期有意义的故事。

**不过，就算以上这样你都做了，也可能一点流量都没有！**😂 

## AiGC 软件工具

在有了内容以后，就是 AI 生成视频了。AI 生成视频的软件有很多，基本也都是付费的。😂 所以说，你不一定赚不赚钱，但 AI 创作课程和 AI 软件是赚钱。

我体验了，可灵 AI、录咖 AI，还有抖音剪映自带的 AI 生成类工具。可灵 AI 适合文生图片、数字人口播，剪映 AI 适合文生视频。因为我本身就需要日常剪辑视频，开了剪映会员，所以可以直接使用。可灵 AI 是少量付费体验了下。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-04.png" width="750px">
</div>

- 剪映 APP 有个 AI 图片成片，进入后选择 AI 故事成片。
- 你可以把 DeepSeek/AI 生成口播故事（2000字 - 3000字），放进来转换即可。完成后，把视频下载下来，上传到你的各个平台。

## 我以为一分钱也赚不到的时候！

**在我折腾了快一周，以为分币赚不到的时候，来活了！**

有个“粉丝”，关注了我。给我讲，接活不。我问啥活，她说，关注这个没事主播，点赞视频和收藏，完成后给6块钱。我没想到，她真给！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-05.png" width="350px">
</div>

o(╥﹏╥)o 这是我做 AIGC 的第一笔收入！虽然，它看起来不正常！

晚上，这个粉丝小姐姐，问我还做不。我说行，她说你要大量做，要下载一个软件“魅信”。我去TM的，我是一个程序员，能信你这！不是“魅信”可怕，是你给我来个自动录屏，整走我点信息不完犊子了。

所以，我给这假粉丝讲！我是一个程序员，我对这个不放心，我不做了！没过多久，我就看XXX视频平台给这个假粉丝账号封了，没法查看完整聊天。以至于我只能截图这一丢丢，给大家看。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-06.png" width="150px">
</div>

- 因为它的账号被封了，已经看不到内容了。只能通过录制视频，在截取一下。不过截取不全了。
- 所以，如果你遇到这种的，赚个6块就跑吧🏃🏻‍！

## 回到本质，仍然是技术！

说到底，其实做各类东西都需要大量的时间精力投入，也有努力 + 运气，才可能有机会做成。想随随便便加个“副业社群”，不一定都能赚到什么钱。

就像你自己，如果用了大量的核心知识储备，那么你所用的这些产品就是工具，反之他们就不是工具，而是收割你的工具。

所以，作为研发人员，我们储备多的是技术知识，可以依赖于技术底层的积累，增强对工具的实现技术了解。看看这样的 AIGC 工具是如何实现的，能部署一个深入了解不，看看API接口从哪调用的，以后我们自己搞下是不更好。

### 1. 软件部署

有这么一个开源软件「利用AI大模型，一键生成高清短视频 Generate short videos with one click using AI LLM.」，可以通过 Docker 部署体现。

代码：[https://github.com/harry0703/MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo)

**docker-compose.yml**

```java
services:
  webui:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/moneyprinterturbo:latest
    container_name: MPTwebui
    ports:
      - "8501:8501"
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "2m"
    command: >
      streamlit run /MoneyPrinterTurbo/webui/Main.py
      --browser.serverAddress=127.0.0.1
      --server.enableCORS=True
      --browser.gatherUsageStats=False
  api:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/moneyprinterturbo:latest
    container_name: MPTapi
    ports:
      - "8080:8080"
    restart: unless-stopped
    logging:
      options:
        max-size: "2m"
    command: python3 /MoneyPrinterTurbo/main.py
```

- 通过 Docker Compose 脚本，执行软件安装。`docker-compose -f docker-compose.yml up -d` 来执行安装。
- 安装后访问 ip:8501

### 2. 访问服务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-07.png" width="950px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-10.png" width="950px">
</div>

- 首先，需要点开设置。配置你的 openai 地址服务，之后配置 [Pexels API Key](https://www.pexels.com/api/key/) 
- 之后，填写文案，文案也可以由 AI 工具生成复制进来。之后点击生成视频（其他选型也可以尝试更换）。
- 最后，生成完视频，就可以扔了。这个效果基本就是体验，与剪映那个差太多了。

### 3. 访问API

AIGC 相当于根据你的文案，检索/生成对应图片，好的AI产品会设置分镜头不同视角的检索。在结合这些图片、视频资源合成你最后要生成的视频效果。

如：[https://www.pexels.com/](https://www.pexels.com/) 就是一个图片视频资源库，你可以免费申请一个 API，之后使用它来生成图片。它的官网有对应的文档描述使用。举例如下；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-09.png" width="950px">
</div>

```java
curl -H "Authorization: 8aHBe0CyGtMZVMji32RVEvgzIRNx38rrkHlbp9HK*****申请你的" \
  "https://api.pexels.com/v1/search?query=美女&per_page=1"
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aigc-08.png" width="550px">
</div>

- 调用接口返回的 JSON 可以查看图片信息，基本你要的内容还是可以大部分时候准确获取的。
- 如果感兴趣，还可以深入体验下它的 API。

---

### Md Road Map Aliyun Workbench (`docs/md/road-map/aliyun-workbench.md`)

---
title: Docker 镜像构建 - Aliyun
lock: need
---

# Docker 镜像构建 - Aliyun

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=114633499215274&bvid=BV1sHTAznEVL&cid=30342449895&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

对于搞编程开发的伙伴来说，我一直都推荐使用 Mac 电脑，因为 Windows 电脑除了相对省点钱，其他的什么也不省！为啥？那我 Windows 电脑推沟里？

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-01.png" width="150px">
</div>

**大厂更多的都是给程序员👨🏻‍💻配Mac！**

其实到也不是 Windows 不好，只是在编程开发中的环境配置，要有太多的额外的兼容问题。因为 Windows 是一个系统，这个系统被各个厂商使用，安装到自己家的电脑上。因此一个软件安装后，不同的机器，都可能在一些细节功能上，有自己的差异化处理方案。就像 Docker 安装，Mac 电脑直接安装即可，Windows 不是安装虚拟机，就是搞个 wsl2，不少小白基本就在这崩溃了。

相对说，Mac 电脑就好的多，因为人家的系统只给自己家的电脑使用。所以各类软件的安装和使用也不会有那么多的适配问题了。另外 Mac 电脑也等同于是在 Linux 上做开发，你的所有编程中使用的命令，几乎就是无差别的可以在云环境 Linux 执行。因此，Mac 电脑除了不省钱，其他的都省；省时、省心、省力。

不过，Windows 电脑也不能推沟里呀！所以，我们要想点办法，让一些如 Docker 的环境安装和镜像构建，让外部系统解决。不就可以了噻！

>接下来，小傅哥就教大家搞一下这个事情。—— 学到手的全是技术！

## 一、DevOps 流水线

DevOps 流水线，是一种可持续集成交付的手段。用户可以使用流水线自定义编排项目发布过程中所涉及的代码打包、单元测试、自动部署等各项阶段。 通过一系列自动化任务的组合解决日常开发工作中繁琐而重复的任务。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-01.png" width="750px">
</div>

官网（JD）：[https://docs.jdcloud.com/cn/devops/application-scenarios](https://docs.jdcloud.com/cn/devops/application-scenarios)

---

市面上也有很多的免费的可持续交付工具，方便我们自己部署项目使用。如 [Github Actions](https://bugstack.cn/md/road-map/github-actions-workflows.html)、[buddy.works](https://bugstack.cn/md/road-map/buddy.html)、[Jenkins](https://bugstack.cn/md/road-map/jenkins.html)，这些已经在 [bugstack.cn](https://bugstack.cn/) 编程路书（发布部署）中分享。今天小傅哥再分享一个阿里云的 DevOps 流水线操作，实际使用体验效果还不错。

## 二、云效工作台介绍

本次案例会涉及到使用阿里云效平台的 `代码管理`、`流水线配置`、`容器镜像`

### 1. 代码&流水线

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-02.png" width="850px">
</div>

- 地址：[https://devops.aliyun.com/workbench](https://devops.aliyun.com/workbench)
- 说明：用于管理工程代码和配置流水线。你可以提交本地代码，也可以把其他仓库的代码导入到`代码管理`中，如；Github、Gitee、Gitlab，其他的也可以通过 url 导入。

### 2. 容器镜像服务

#### 2.1 容器申请

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-03.png" width="850px">
</div>

- 地址：[https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard](https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard)
- 说明：容器镜像，相当于代理的 [Docker Hub](https://hub.docker.com/) 可以把我们通过流水线构建的项目（SpringBoot/React/...）构建的镜像，放到容器镜像服务中。之后就可以在其他云环境或者本地环境拉取使用了。

#### 2.2 新建服务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-09.png" width="550px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-10.png" width="550px">
</div>

- 这里要新建一个镜像名称，`xfg-dev-tech-aliyun-workbench` 的镜像。这个镜像为后续的流水线构建使用。
- 创建的时候，要选择对应的仓库。可以是 Codeup 的阿里云代码库，也可以是 Github 关联地址的仓库。

> 再往下开始平台，你需要注册一个云校平台和容器镜像服务。

## 三、上传代码库

这部分会涉及一些 Git 的操作，这里小傅哥准备好了教程可以使用 [https://bugstack.cn/md/road-map/git.html](https://bugstack.cn/md/road-map/git.html)

### 1. 案例工程

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-04.png" width="350px">
</div>

```java
# 基础镜像 openjdk:8-jre-slim 代理地址；registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:8-jre-slim
FROM registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 在容器内创建目录/home/project 用于存放应用程序和相关文件
RUN mkdir -p /home/project

# 设置工作目录为/home/project，即后续的命令都在这个工作目录下执行。
WORKDIR /home/project

# 添加应用
ADD xfg-dev-tech-app/target/xfg-dev-tech-app.jar /home/project/xfg-dev-tech-app.jar

## 在镜像运行为容器后执行的命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /home/project/xfg-dev-tech-app.jar $PARAMS"]
```

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-aliyun-workbench](https://github.com/fuzhengwei/xfg-dev-tech-aliyun-workbench)
- 说明：这里小傅哥给你准备好了一个测试工程，你可以使用验证阿里云效流水线操作。
- 脚本：注意配置的脚本信息，如果你是新的其他的工程，可以参考配置。

### 2. 上传项目

把案例代码上传到阿里云代码库的方式有很多，可以从 Github 导入，也可以先把代码拉取到本地，在从本地上传到阿里云代码库。但两个方式都建议把代码拉取到本地代码一份，方便进行修改。

#### 2.1 导入代码

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-05.png" width="950px">
</div>

- 首先，进入案例工程地址（Github），点击 Fork 克隆到自己的仓库中。
- 之后，在阿里云效点击导入仓库，这里可以选择从 Github 导入。导入的时候，需要填写 Access Token。创建地址：[https://github.com/settings/tokens](https://github.com/settings/tokens)
- 最后，在确认后会展示你的 Github 仓库列表，选择要导入的工程即可。

#### 2.2 上传代码

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-06.png" width="950px">
</div>

- 首先，开始操作之前，你要把提供的案例代码拉取到本地。
- 之后，在云效代码库，新建一个代码库。新建后可以获得一个 https 提交代码库的地址。另外，要注意你还要在云效仓库个人设置里，创建一个，个人访问令牌（地址：[https://account-devops.aliyun.com/settings/profile](https://account-devops.aliyun.com/settings/profile)）。
- 最后，在自己 Intellij IDEA 菜单栏上，点击 Git 选择 Manage Remotes 添加阿里云效仓库地址，之后就可以把代码提交到阿里云效了。

### 3. 添加流水线

#### 3.1 构建操作

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-11.png" width="950px">
</div>

- 如图，配置构建信息。注意，☑️ 制品中包含打包路径的目录。

#### 3.2 添加步骤；Docker镜像构建

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-12.png" width="750px">
</div>

- 添加新的步骤，选择构建并推送至ACR（个人版）注意配置路径正确。

#### 3.3 添加步骤；邮件通知

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-13.png" width="750px">
</div>

- 添加一个邮件通知的插件，构建后会接收到邮件。

### 4. 构建镜像

#### 4.1 执行构建

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-14.png" width="950px">
</div>

- 点击运行，之后就可以构建镜像了。如果哪个节点失败了，可以点日志查看失败原因。

#### 4.2 构建结果

##### 4.2.1 邮件通知

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-17.png" width="450px">
</div>

- 你会收到一个来自云效构建的通知邮件。代表着构建的结果。

##### 4.2.2 查看镜像

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-15.png" width="950px">
</div>

- 构建完成镜像后，可以进入`容器镜像服务`中找到镜像。地址：[https://cr.console.aliyun.com/cn-hangzhou/instance/repositories](https://cr.console.aliyun.com/cn-hangzhou/instance/repositories)
- 之后还可以通过公网地址拉取镜像，命令：`docker pull registry.cn-hangzhou.aliyuncs.com/fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0`

##### 4.2.3 拉取镜像

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-aliyun-workbench-16.png" width="950px">
</div>

```java
[root@hcss-ecs-decd ~]# docker pull registry.cn-hangzhou.aliyuncs.com/fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0
1.0.0: Pulling from fuzhengwei/xfg-dev-tech-aliyun-workbench
1efc276f4ff9: Already exists 
a2f2f93da482: Already exists 
1a2de4cc9431: Already exists 
d2421c7a4bbf: Already exists 
64e0330ea35f: Pull complete 
4da07e374896: Pull complete 
4f4fb700ef54: Pull complete 
eb9d0e194679: Pull complete 
Digest: sha256:a7af08fff4ea0b76184a2fad7e7ca639ab4a9ad16573480b526eda672ed8a483
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0
registry.cn-hangzhou.aliyuncs.com/fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0
[root@hcss-ecs-decd ~]# docker tag registry.cn-hangzhou.aliyuncs.com/fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0 fuzhengwei/xfg-dev-tech-aliyun-workbench:1.0.0
[root@hcss-ecs-decd ~]# docker images
REPOSITORY                                                                   TAG       IMAGE ID       CREATED          SIZE
fuzhengwei/xfg-dev-tech-aliyun-workbench                                     1.0.0     df740ba425bb   24 minutes ago   221MB
```

- 镜像构建完成后，就可以在云服务器上拉取镜像了。
- 好啦，到这你就可以愉快的完善了，前端构建镜像也是一样的操作。

---

### Md Road Map Apisix (`docs/md/road-map/apisix.md`)

---
title: apisix
lock: need
---

# Apisix 云原生架构的开源 API 网关

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

`Higress`、`SpringCloud Gateway`，再到今天这套 `Apisix` 小傅哥就把市面上非常常用的3套 API 网关服务就全部都展示给大家了。其实所有的 API 网关都有一个共同的目的，就是做统一的 API 管理，包括；协议转换、负载均衡、动态路由、灰度发布、服务熔断、统一认证等。

像是这些组件化的 API 网关，使用起来其实都挺容易的，就有点像是使用了一个可视化的 Nginx 一样。但这些 API 看着简单，但有时候没有一个不错的资料对照搭建、配置和使用，也是挺难下手的。所以小傅哥把这些内容，成体系的展示给你，让你可以对照学习使用。

- 官网：[https://apisix.apache.org/zh/](https://apisix.apache.org/zh/)
- 部署：[https://github.com/apache/apisix-docker](https://github.com/apache/apisix-docker) - 官网提供了 Docker 脚本，但也有一些注意事项才能使用
- 脚本：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-apisix](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-apisix) - 可执行使用的部署脚本

## 一、APISIX 介绍

这款老6API，是阿帕奇下的开源项目。最初由 [api7.ai](https://api7.ai/apisix) 创建，于 2019 年开源并捐献给 Apache 软件基金会，使服务全球一半 API 请求的愿景成为可能。自那时起，API7.ai一直投入最优秀的人才和资源来支持 Apache APISIX 及其社区，该社区由来自世界各地的数千名贡献者和用户加入。

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关，提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-01.png" width="750px">
</div>

为什么选择 Apache APISIX?

- 简单易用的 Dashboard：Apache APISIX Dashboard 可以让用户尽可能直观、便捷地通过可视化界面操作 Apache APISIX。作为 Apache 软件基金会中持续迭代的开源项目，欢迎你随时提出新的想法。
- 友好的用户体验：Apache APISIX Dashboard 极大地满足了用户需求，不仅提供了清晰的组织架构以适配二次开发，而且可以借助插件编排能力释放想象力！
- 可视化配置：拒绝重复造轮子。借助 Apache APISIX 内置插件，可以在极短时间内创建灵活、可靠、高性能的网关。无需编写代码，只需在编辑器中拖拽插件、配置条件，便可通过可视化的方式打造专属的 API 管理系统。
- 极致的性能体验：Apache APISIX 基于 Radixtree Route 和 etcd 提供路由极速匹配与配置快速同步的能力。从路由到插件，所有的设计和实现都是为了极速性能和超低延迟。
- 阻拦恶意程序：Apache APISIX 提供了多款身份认证与接口验证的插件，我们将稳定、安全放在首位。

## 二、环境部署

- 云服务器：2c2g 最低，我是用的 2c8g 体验的。[https://yun.xfg.plus](https://yun.xfg.plus/) - 价格实惠。
- 基础环境：Docker、Portainer、Git 【在小傅哥的 bugstack.cn 路书中都有讲解安装和使用】

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-02.png" width="950px">
</div>

### 1. 脚本配置

官网中提供了 docker 的安装脚本，但不能直接使用，需要如图做下复制操作。小傅哥已经把这部分复制的内容，到`脚本`工程里了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-03.png" width="450px">
</div>

- 你可以知道有这么一个地方，将来如果版本更新了，也可以做下配置操作。

### 2. 可用脚本 - 准备好的

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-04.png" width="650px">
</div>

- 这个是小傅哥帮你准备好的脚本，可以直接安装使用。
- 这里涉及了 docker、portainer 的使用，在《[bugstack.cn](https://bugstack.cn) 路书》中，已经完整配置提供，可以查看。

## 三、网关配置

- 网关的登录密码是在 dev-ops/apisix-dashboard/conf.yaml 中配置的。默认的是 `admin/admin`
- 另外注意 conf.yml 中 etcd:2379 的配置，这里从 127.0.0.1 调整为 etch 应用名称。这样能保证在同一个 docker 配置的网络下，可以直接连接使用。如果是分布式部署，则要改为具体的IP。
- 这套按照学习脚本中提供了 web1、web2 两个 nginx 的配置，可以测试使用。

### 1. 访问网关

地址：[http://127.0.0.1:9093/](http://127.0.0.1:9093/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-05.png" width="450px">
</div>

- 访问后就可以看到左侧的目录，可以配置；服务、上游、路由，以及插件等功能。
- 路由是入口，从路由可以访问到配置的服务，服务是每个应用的访问地址，可以配置权重轮训和一致性哈希。插件主要是提供的是；身份验证、安全防护、流量控制、无服务架构、可观测性功能。

### 2. 服务配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-06.png" width="850px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-07.png" width="850px">
</div>

- 配置后，一直点击就可以了。

### 3. 配置路由

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-08.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-09.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-10.png" width="750px">
</div>

### 4. 插件配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-11.png" width="750px">
</div>

- 你可以按需测试各种插件，还可以通过编排让各个要执行的插件串联起使用。

## 四、服务验证

地址：[http://192.168.1.105:9080/api](http://192.168.1.105:9080/api)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-apisix-12.png" width="750px">
</div>

- 刷新网关接口，不停的刷新，会看到接口访问值的变化。

---

### Md Road Map Arex Test (`docs/md/road-map/arex-test.md`)

---
title: AREX - 流量录制&回放
lock: need
---

# AREX - 流量录制&回放

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

在互联网大厂应用系统开发中，有一项非常重要的技术手段，保证新迭代功能的可靠性。虽然，这像技术也不是“银弹（啥都能搞定）”，但缺少这项技术，对于极其复杂的业务场景新上线功能，总感觉心里没底！—— 它就是`流量录制`和`流量回放`！

<div align="center">
    <img src="https://bugstack.cn/images/article/zsxq/student-learn-01.gif" width="150px">
</div>

**如何保证系统的可靠性？**

互联网大厂toc场景，非常重视交付的可靠性，甚至大于交付的效率性。所以，在整个研发声明周期过程中，要有 PRD 评审、研发设计代码、代码评审、代码分支合并评审，以及在这个过程中还有测试人员进行全流程的验证。

但即使这样，面对经历了数十年迭代的系统，单工程甚至几十万行代码，极其复杂的业务系统流程，测试也是可能会出现疏漏。这种疏漏如，虽然非本次需求迭代的场景，但是其他业务场景因当前系统的一个枚举，一个参数的变动，都会影响到数十条业务。哪怕不是代码变动，仅仅是重构了小部分代码块，调整了前后顺序，当前业务无影响，但确影响了某次其他任务的跑批结果！

一次事故，可能是扣绩效和年终奖，也可能是影响晋升提名，还可能是直接毕业🎓啦！所以，在互联网大厂班组🧱搬砖，会学到很多高级技巧，来保证系统的可靠性。

>关注小傅哥 [bugstack.cn](https://bugstack.c) 博客，编程路书，可以学习到非常多的互联网企业使用技能，补全自己的短板！如；系统架构、开发环境、开发技术、授权框架、常用类库、工程测试、质量监控、发布部署等。

## 一、说说概念

其实简单来讲，流量录制，核心的本质就是把线上运行的应用，在有流量请求到服务接口后，把请求接口的入参和执行的结果，都保存下来。之后流量回放，则是把这些保存下来的入参信息，在开发环境/测试环境/预发环境，进行请求，之后验证请求后的结果是否与线上录制的流量结果一致。整个的这个过程，就是流量的录制和回放。

但实际的操作场景要比这个过程复杂，如；录制流量的操作，要无侵入代码的，要把整个调用链路，全部录制下来，而不是单个接口。同时录制的不只是对接口的操作，还有缓存、rpc、数据库（MyBatis）、es，等各类组件兼容，都能确保可正确录制到完整数据，以便在流量回放时，可以mock掉数据接口，以此只验证功能逻辑。

说到，逻辑和数据，这里想到了DDD架构的领域层和基础设施层，领域层（domain）专门业务功能逻辑的，而基础设置层（infrastructure）则是提供数据的。这样有了业务功能和数据获取的分离，不让核心业务逻辑又掺杂外部接口的调用，其实维护和迭代起来，是会更加容易的。

## 二、讲讲原理

为了可以无侵入式的完成系统的流量录制和流量回放，这里引入了一个 Java Agent 字节码增强技术，通过在程序启动阶段，对工程代码的方法进行埋点。这个埋点，就等同于动态的通过 class 文件写入新的代码，新的代码可以采集到方法的出入参信息，并把这些信息发送到流量录制存储方，或者执行时进行mock接口请求结果处理。

这部分技术方案，小傅哥于19-20年，编写了先关的技术资料。其中包括了用于处理字节码增强技术的，asm、javassist、byte-buddy 三种框架。

<div align="center">
    <img src="https://bugstack.cn/assets/images/2020/itstack-demo-asm-02-1.png" width="750px">
</div>

文档：[https://bugstack.cn/md/bytecode/asm/2020-04-05-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5DJavaAgent+ASM%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E9%87%87%E9%9B%86%E6%96%B9%E6%B3%95%E5%90%8D%E7%A7%B0%E4%BB%A5%E5%8F%8A%E5%85%A5%E5%8F%82%E5%92%8C%E5%87%BA%E5%8F%82%E7%BB%93%E6%9E%9C%E5%B9%B6%E8%AE%B0%E5%BD%95%E6%96%B9%E6%B3%95%E8%80%97%E6%97%B6.html](https://bugstack.cn/md/bytecode/asm/2020-04-05-%5BASM%E5%AD%97%E8%8A%82%E7%A0%81%E7%BC%96%E7%A8%8B%5DJavaAgent+ASM%E5%AD%97%E8%8A%82%E7%A0%81%E6%8F%92%E6%A1%A9%E9%87%87%E9%9B%86%E6%96%B9%E6%B3%95%E5%90%8D%E7%A7%B0%E4%BB%A5%E5%8F%8A%E5%85%A5%E5%8F%82%E5%92%8C%E5%87%BA%E5%8F%82%E7%BB%93%E6%9E%9C%E5%B9%B6%E8%AE%B0%E5%BD%95%E6%96%B9%E6%B3%95%E8%80%97%E6%97%B6.html)

### 1. 增强代码

```java
mv.visitVarInsn(LLOAD, startTimeIdentifier);
mv.visitLdcInsn(methodId);
if (parameterTypeList.isEmpty()) {
    mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(ProfilingAspect.class), "point", "(JI)V", false);
} else {
    mv.visitVarInsn(ALOAD, parameterIdentifier);  // 5
    mv.visitVarInsn(ALOAD, localCount);           // 6
    mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(ProfilingAspect.class), "point", "(JI[Ljava/lang/Object;Ljava/lang/Object;)V", false);
}
```

### 2. 拦截信息

```java
ASM类输出路径：/Users/xiaofuge/itstack/git/github.com/SQM/target/test-classes/org/itstack/test/ApiTest$1SQM.class
监控 - Begin
类名：org.itstack.test.ApiTest
方法：queryUserInfo
入参类型：["I","I"]
入数[值]：[111,17]
出参类型：Ljava/lang/String;
出参[值]："你好，bugstack虫洞栈 | 精神小伙！"
耗时：95(s)
监控 - End

测试结果：你好，bugstack虫洞栈 | 精神小伙！
```

- 以上为简要的案例代码，通过ASM字节码增强框架来对方法修改，增加日志打印信息，在执行方法时，获取出入参。
- 字节码增强技术应用的方面非常多，如；MapStruct、非入侵的全链路监控、Lombok，甚至你用过的 IntelliJ IDEA 破解也是字节码增强技术。

## 三、工具介绍

关于流量录制和流量回放的工具是蛮多的，其中包括；[jvm-sandbox-repeater](https://github.com/alibaba/jvm-sandbox-repeater)、[MoonBox](https://github.com/vivo/MoonBox)、[arextest](https://arextest.com/) 等。

- jvm-sandbox-repeater，是一个基于 JVM-Sandbox 采用Java来实现的流量录制回放工具，或者可以理解为它是一个基于Java虚拟机的插件，可以直接运行中JVM中，无需对目标应用程序进行任何修改。
- Moonbox（月光宝盒），是一个无侵入的线上流量录制 和流量回放平台，沿用了jvm-sandbox-repeater的SPI设计，并提供了大量的常用插件，同时也提供数据统计和存储能力。通过Moonbox可以实现自动化测试、线上问题追踪、和业务监控等能力
- arextest，AREX 通过将真实的在线流量复制到测试环境进行自动化 API 测试来解决自动化测试的挑战。**作为本文分享场景工具使用。**

**名词解释**

- **录制**：把一次请求的入参、出参、**下游RPC、DB、缓存**等序列化并存储的过程
- **回放**：把录制数据还原，重新发起一次或N次请求，对特定的下游节点进行MOCK的过程
- **入口调用**：入口调用一般是应用的**流量来源**，比如http/dubbo，在调用过程中录制调用入参，返回值。回放时作为流量发起和执行结果对比依据
- **子调用**：区别于入口调用，子调用是调用执行过程中某次方法调用。子调用在录制时会记录该方法的入参、返回值；回放时用该返回值进行MOCK
- **MOCK**：在回放时，被拦截的子调用**不会发生真实调用**，利用字节码动态干预能力，将录制时的返回值直接返回
- **降噪**：在回放时，部分回放子调用入参或者回放流量响应结果和原始流量对比不一致字段，对这些非必要字段进行排除对比过程

## 四、工具使用

### 1. 案例工程

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-01.png" width="800px">
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-traffic-agent](https://github.com/fuzhengwei/xfg-dev-tech-traffic-agent)
- 如图：1~6点，说明了各个模块的用途。
- 提示：建议使用云服务器部署流量录制&回放服务，非常方便。

### 2. 安装插件

地址：[https://chromewebstore.google.com/detail/arex-chrome-extension/jmmficadjneeekafmnheppeoehlgjdjj](https://chromewebstore.google.com/detail/arex-chrome-extension/jmmficadjneeekafmnheppeoehlgjdjj)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-04.png" width="800px">
</div>

- 安装插件是为了有权限访问接口。

### 3. 服务部署（arex）

**前置条件**，2c4g云服务器，完成初始化Docker环境。这里有一键安装脚本，[https://bugstack.cn/md/road-map/docker-install.html](https://bugstack.cn/md/road-map/docker-install.html)

```java
[root@iv-jdyun ~]# cd /
[root@iv-jdyun ~]# mkdir dev-ops
[root@iv-jdyun ~]# cd dev-ops
[root@iv-jdyun ~]# sudo yum install git
[root@iv-jdyun ~]# git clone --depth 1 https://github.com/arextest/deployments.git
[root@iv-jdyun ~]# cd deployments
[root@iv-jdyun ~]# docker-compose up -d
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-02.png" width="800px">
</div>

- 执行脚本安装完成后，在云服务器安全组开放端口号（出/入规则）。
- 之后访问：http://ip:8088 首次访问会慢一些，进入后会让设置你的登录账号。

### 4. 启动项目 - 录制流量

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-03.png" width="900px">
</div>

- 首先，需要给项目工程加入一个 agent，来录制和回放。arex 的 agent jar，下载后方到工程下，lib 中。目前工程中已经下载了，如果将来有更新，可以重新下载最新的。地址：[https://github.com/arextest/arex-agent-java/releases](https://github.com/arextest/arex-agent-java/releases)
- 之后，本地项目测试验证的时候，可以先 **install**，成功之后使用 `run_application_2_agent.sh` 启动项目，这个操作会把 agent 加载到程序启动中。

#### 4.1 本地测试

```java
#!/bin/bash

# AREX Agent 启动脚本
# 用于在不同环境下启动应用并加载 AREX Agent

# 设置 AREX Agent 相关参数
AREX_AGENT_PATH="./lib/arex-agent.jar"
AREX_SERVICE_NAME="xfg-dev-tech-app"
AREX_STORAGE_HOST="115.190.107.206:8093"

# 应用 JAR 包路径（相对于项目根目录）
APP_JAR="../../xfg-dev-tech-app/target/xfg-dev-tech-app.jar"

# JVM 参数
JVM_OPTS="-Xms512m -Xmx1024m"

# 检查 AREX Agent 文件是否存在
if [ ! -f "$AREX_AGENT_PATH" ]; then
    echo "错误: AREX Agent 文件不存在: $AREX_AGENT_PATH"
    echo "请确保 arex-agent.jar 文件已放置在正确位置"
    exit 1
fi

# 检查应用 JAR 包是否存在
if [ ! -f "$APP_JAR" ]; then
    echo "错误: 应用 JAR 包不存在: $APP_JAR"
    echo "请先执行 mvn clean package 构建应用"
    exit 1
fi

echo "正在启动应用..."
echo "AREX Agent: $AREX_AGENT_PATH"
echo "Service Name: $AREX_SERVICE_NAME"
echo "Storage Host: $AREX_STORAGE_HOST"
echo "Application: $APP_JAR"
echo ""

echo "执行配置："$JVM_OPTS \
          -javaagent:"$AREX_AGENT_PATH" \
          -Darex.service.name="$AREX_SERVICE_NAME" \
          -Darex.storage.service.host="$AREX_STORAGE_HOST" \
          -jar "$APP_JAR"

# 启动应用
java $JVM_OPTS \
     -javaagent:"$AREX_AGENT_PATH" \
     -Darex.service.name="$AREX_SERVICE_NAME" \
     -Darex.storage.service.host="$AREX_STORAGE_HOST" \
     -jar "$APP_JAR"
```

#### 4.2 docker 镜像

##### 4.2.1 dockerfile

```java
# 基础镜像
FROM openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# AREX Agent 配置
ENV AREX_SERVICE_NAME="xfg-dev-tech-app"
ENV AREX_STORAGE_HOST="115.190.107.206:8093"

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加 AREX Agent
ARG AREX_AGENT_PATH=docs/dev-ops/lib/arex-agent.jar
ADD ${AREX_AGENT_PATH} /arex-agent.jar

# 添加应用
ADD target/xfg-dev-tech-app.jar /xfg-dev-tech-app.jar

ENTRYPOINT ["sh","-c","java $JAVA_OPTS -javaagent:/arex-agent.jar -Darex.service.name=$AREX_SERVICE_NAME -Darex.storage.service.host=$AREX_STORAGE_HOST -jar /xfg-dev-tech-app.jar $PARAMS"]
```

##### 4.2.2 docker-compose

```java
version: '3.8'

services:
  xfg-dev-tech-app:
    image: fuzhengwei/xfg-dev-tech-app:traffic-agent-v1
    container_name: xfg-dev-tech-app
    ports:
      - "8091:8091"
    environment:
      # AREX Agent 配置
      - AREX_SERVICE_NAME=xfg-dev-tech-app
      - AREX_STORAGE_HOST=115.190.107.206:8093
      # JVM 配置
      - JAVA_OPTS=-Xms512m -Xmx1024m
    volumes:
      # 日志目录挂载（可选）
      - ./data/logs:/var/log/app
    networks:
      - app-network
    restart: unless-stopped
    
networks:
  app-network:
    driver: bridge

volumes:
  app-logs:
    driver: local
```

- 此方式适用于项目部署上线。

### 5. 启动程序

```java
./bin/bash /xfg-dev-tech-traffic-agent/docs/dev-ops/run_application_2_agent.sh
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 启动程序，会看到 arex-agent.jar 的加载，这代表是正确✅的，可以上报服务信息。

### 6. 流量录制

```java
@Slf4j
@RestController
@RequestMapping("/api/traffic")
public class TrafficController {

    @GetMapping("/query_user_age")
    public Integer queryUserAge(@RequestParam("userId") String userId) {
        log.info("请求参数:{}", userId);
//        return getCache();
        return getDB();
    }

    // 模拟从缓存获取数据
    public Integer getCache() {
        return 20;
    }

    // 模拟从数据库获取数据
    public Integer getDB() {
        return 21;
    }

}
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-05.png" width="600px">
</div>

- 你可以使用工程下，test-api-curl.sh 脚本访问接口，也可以其他方式请求接口。
- 当你请求完成接口后，就可以去arex控制台检查上报的信息和流量录制的数据了。

### 7. 流量回放

#### 7.1 内网穿透

流量回放是从云服务器调用本地，但本地没有对外的公网IP，所以需要内网穿透，让云服务器可以调用。这里的内网穿透工具很多，可以选择；[natapp](https://natapp.cn/)、[cpolar.com](https://www.cpolar.com/) 等。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-06.png" width="800px">
</div>

```java
Powered By NATAPP       Please visit https://natapp.cn                                                                                                                                     (Ctrl+C to Quit)
                                                                                                                                                                                                           
Tunnel Status           Online                                                                                                                                                                             
  
Version                 2.3.9 (New Version 2.4.0)     
  
Forwarding              http://xfg-studio.natapp1.cc -> 127.0.0.1:8091                                                                                                                                     

Web Interface           Disabled                                                                                                                                                                           
                                                                                     
Total Connections       0                                                                                                                                        
```

- 启动后，会把本地的服务:端口，暴漏出去，通过 http 域名地址访问。
- 注意，在natapp配置你的应用端口，如 8091，如果是其他就修改下。

#### 7.2 回放配置 - 正确回放

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-07.png" width="800px">
</div>

- 如图，填写回放配置信息。
- 这次我们是正确回放，也就是本地程序没有任何变更。配置后点OK。
- 点击后，可以在我们本地服务看到回调的日志，但还要稍微等待一会 arex 平台，他要比对回放结果。完成后，Passed 表示回放通过。

#### 7.2 回放配置 - 异常回放

首先，我们要修改下代码。

```java
@RestController
@RequestMapping("/api/traffic")
public class TrafficController {

    @GetMapping("/query_user_age")
    public Integer queryUserAge(@RequestParam("userId") String userId) {
        log.info("请求参数:{}", userId);
//        return getCache();
        return getDB();
    }

    // 模拟从缓存获取数据
    public Integer getCache() {
        return 20;
    }

    // 模拟从数据库获取数据
    public Integer getDB() {
        return 21;
    }

}
```

- 这个接口方法，如果录制流量是用的 getCache()，那么这会就修改为 getDB()，让两次结果不一样。
- 之后，要重新 install 并重新执行 `run_application_2_agent.sh` 启动项目。关闭执行 Ctrl/Command + C

配置，流量回放操作。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-08.png" width="600px">
</div>

- 之后，再来一遍回放。这样就是错误的结果了。

### 8. 接口请求（Debug）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-traffic-agent-09.png" width="800px">
</div>

- arex 工具，还支持线上请求本地接口操作。
- 也就是说，你从线上录制的流量，可以直接拿流量，调试本地接口。有了这样一个操作，哪些线上请求参数非常复杂的结构，就可以直接一键对本地进行验证了。

---

### Md Road Map Arthas (`docs/md/road-map/arthas.md`)

---
title: arthas
lock: need
---

# 面试官：“程序内存溢出，你怎么找出大对虾(像)”？ —— arthas 使用教程

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=113339371947965&bvid=BV1vTyaYeEHq&cid=26380012483&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

👬🏻 兄弟，你被看过手相不，你被号过脉相没。一个没与你生活过就知道你的过去和现在，一个不了解你的日常就知道你是否怀孕是男是女。而你自己亲手开发的Java代码，上线后报错都不知道怎么发生的！！！咋办？

<div align="center">
    <img src="https://bugstack.cn/images/article/zsxq/student-learn-01.gif" width="150px">
</div>

**那有什么手段给 Java 代码号脉吗？🤔**

还真有这么一个工具，也是大多数老司机程序员👨🏻‍💻非常喜欢用的一款组件，很多时候不好排查的 Bug 都用这个工具进行分析。它可以知道哪个对象创建的过多、方法的出入参、系统运行时候JVM的参数等等，让你随时可以知道系统运行的细节状态。

它就是 Arthas，但很多伙伴还没有使用过，这篇文章为大家分享下，如何使用这样一款组件。以及怎么使用这个组件监控部署到 Docker 中的 Java 应用。

## 一、组件介绍

官网：[https://arthas.aliyun.com/doc/](https://arthas.aliyun.com/doc/)

Arthas 是一款线上监控诊断产品，通过全局视角实时查看应用 load、内存、gc、线程的状态信息，并能在不修改应用代码的情况下，对业务问题进行诊断，包括查看方法调用的出入参、异常，监测方法执行耗时，类加载信息等，大大提升线上问题排查效率。

当你遇到以下类似问题而束手无策时，Arthas可以帮助你解决：

1. 这个类从哪个 jar 包加载的？为什么会报各种类相关的 Exception？
2. 我改的代码为什么没有执行到？难道是我没 commit？分支搞错了？
3. 遇到问题无法在线上 debug，难道只能通过加日志再重新发布吗？
4. 线上遇到某个用户的数据处理有问题，但线上同样无法 debug，线下无法重现！
5. 是否有一个全局视角来查看系统的运行状况？
6. 有什么办法可以监控到 JVM 的实时运行状态？
7. 怎么快速定位应用的热点，生成火焰图？
8. 怎样直接从 JVM 内查找某个类的实例？

## 二、快速入门

在 Arthas 官网有一个简单🔜快速入门的案例，它提供了2个程序，一个是 Java 的随机数分解的程序代码，另外一个是 arthas-boot.jar 监控组件。这个套代码可以在任何安装了 Java 环境的服务器上使用，包括你本地、云服务器都可以运行。

### 1. 步骤1，案例程序

```java
curl -O https://arthas.aliyun.com/math-game.jar
java -jar math-game.jar
```

### 2. 步骤2，监控程序

```java
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
```

- 启动后会出来一个 math-game.jar 之后再敲下回车，就进入了 Arthas 的监控程序了。之后你可以使用监控程序提供的各种命令进行使用。
- 命令列表：[https://arthas.aliyun.com/doc/commands.html](https://arthas.aliyun.com/doc/commands.html)

## 三、应用使用

### 1. 环境准备

为了方便大家进行学习验证，小傅哥这里准备好了一个测试工程和相关的环境安装。你可以如下文的说明进行使用和验证。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-01.png" width="450px">
</div>

- 工程：[https://github.com/fuzhengwei/xfg-dev-tech-arthas](https://github.com/fuzhengwei/xfg-dev-tech-arthas)
- 说明：`dev-ops` 下提供了部署测试工程的 docker compose 脚本，以及 arthas-boot 启动程序的脚本。另外工程提供了一个接口，每次访问都会创建对象。接口在 Application 中，简单实现。地址：[http://localhost:8091/api/exec](http://localhost:8091/api/exec) - 接口内容可详见代码。
- 前置：如果你需要云服务器部署操作，可以在 [bugstack.cn](https://bugstack.cn) <路书> 中有云服务器操作，可以学习使用。

### 2. 应用安装

**操作过程预览**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-02.png" width="950px">
</div>

>如图所示，接下来我们会进行部署操作。

#### 2.1 构建脚本

```java
# 基础镜像 openjdk:8-jre-slim openjdk:8-jdk-alpine 8-jdk-alpine
FROM openjdk:8-jdk

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用
ADD target/xfg-dev-tech-app.jar /xfg-dev-tech-app.jar

# arthas https://hub.docker.com/r/hengyunabc/arthas
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas

## 在镜像运行为容器后执行的命令
ENTRYPOINT ["sh","-c","java -Djava.security.egd=file:/dev/./urandom -jar $JAVA_OPTS /xfg-dev-tech-app.jar $PARAMS"]

# 暴露容器的端口
EXPOSE 8989
```

- `FROM openjdk:8-jdk`：因为 arthas 需要 jps 的相关命令，所以需要指定安装 jdk 版本。`openjdk:8-jre-slim` 是没有这些脚本的。
- `hengyunabc/arthas:latest`：把 arthas 的镜像打包到程序中，这样我们可以直接在程序中使用 arthas 组件。
- 构建过程：无论是本地还是云服务器 Docker 启动后，先执行 `maven install` 程序、后执行 `build.sh` 构建应用镜像。[云服务器操作视频](https://bugstack.cn/md/road-map/linux.html)

#### 2.2 部署项目

```java
version: '3.8'
# docker-compose -f docker-compose-app.yml up -d
# 你需要修改system为你自身系统的仓库名
services:
  xfg-dev-tech:
    image: xiaofuge/xfg-dev-tech-app:1.0
    container_name: xfg-dev-tech
    restart: on-failure
    ports:
      - "8091:8091"
    environment:
      - TZ=PRC
      - SERVER_PORT=8091
      # 2c4g 配置，4c8g 翻倍，-Xms4096m -Xmx4096m | -Xmx –Xms：指定java堆最大值（默认值是物理内存的1/4(<1GB)）和初始java堆最小值（默认值是物理内存的1/64(<1GB))
      - JAVA_OPTS=-Xms2048m -Xmx2048m -XX:MaxMetaspaceSize=128m -XX:MetaspaceSize=128m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps
    volumes:
      - ./log:/data/log
      - ./arthas/profiler:/arthas-output
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - my-network

networks:
  my-network:
    driver: bridge
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-03.png" width="650px">
</div>

- 脚本说明；脚本提供了 docker compose 安装的配置参数，包括端口、jvm、日志和arthas的映射路径等。
- 执行脚本；`docker-compose -f docker-compose-app.yml up -d`这样会帮助你启动项目。 
- Mac 电脑 + Docker 可以直接在 IntelliJ IDEA 中点击启动。

### 3. 监控部署

```java
docker exec -it xfg-dev-tech /bin/sh -c "java -jar /opt/arthas/arthas-boot.jar"
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-04.png" width="850px">
</div>

- 在案例工程下有一个 dev-ops/arthas-boot.sh 你可以执行启动 arthas
- 启动后有一个 arthas 的控制台，这个控制台可以输入各种 arthas 提供的命令来监控程序。**非常强大**

### 4. 访问接口

在案例工程中提供了一个用于创建对象的程序，方便进行测试。

```java
@Slf4j
@SpringBootApplication
@RestController()
@RequestMapping("/api/")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    // 创建线程池
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    // 用于存储内存占用对象的列表
    private static final List<Object> memoryHolder = new ArrayList<>();

    /**
     * http://localhost:8091/api/exec
     */
    @RequestMapping(value = "/exec", method = RequestMethod.GET)
    public String exec() {
        executorService.submit(() -> {
            try {
                // 创建一个大对象
//                    byte[] largeObject = new byte[10 * 1024 * 1024]; // 10MB
                byte[] largeObject = new byte[10 * 1024]; // 10MB

                // 将其加入内存占用列表中，防止被gc
                synchronized (memoryHolder) {
                    memoryHolder.add(largeObject);
                }

                log.info("模拟填充大对象");

                // 模拟一些工作
                Thread.sleep(1000);

            } catch (OutOfMemoryError e) {
                System.err.println("Out of memory! Halting further allocation.");
                // 如果出现OOM，暂停分配以防止程序崩溃
                executorService.shutdown();

            } catch (InterruptedException e) {
                // 捕获并处理睡眠中断
                Thread.currentThread().interrupt();
                System.err.println("Task interrupted");
            }
        });
        return "ok";
    }

}
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-05.png" width="650px">
</div>

- 请求地址：[http://localhost:8091/api/exec](http://localhost:8091/api/exec)
- 请求脚本：提供了请求1次和循环多次的脚本，方便测试。

## 四、命令使用

使用监控命令前，可以先执行上图中的 curl-one.sh 调用程序接口。你还可以在使用命令的过程中调用测试。

命令：[https://arthas.aliyun.com/doc/commands.html](https://arthas.aliyun.com/doc/commands.html)

### 4.1 dashboard - 当前系统的实时数据面板

> [arthas@7]$ dashboard

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-06.png" width="950px">
</div>

- 运行脚本后，可以查看到当前服务的运行数据信息。另外这里还有一些 JVM 基础知识，补充给大家。

#### 4.1.1 jvm 内存空间都有啥

在 Java 运行环境中，JVM（Java Virtual Machine, Java 虚拟机）是执行 Java 程序的引擎，而内存管理是 JVM 非常重要的一部分。JDK 1.8 中的 JVM 内存空间主要分为以下几个区域，每个区域都有其特定的用途：

1. 堆（Heap）：
   - 用途：堆是 JVM 中内存最大的一块，用于存储所有的对象实例和数组。几乎所有对象都在此分配内存，垃圾收集器也在这里执行。
   - 分代垃圾收集机制：堆内存被进一步划分为新生代和老年代。
      - 新生代（Young Generation）：用于存放新创建的对象。其中又分为伊甸园区（Eden Space）和两个幸存者区（Survivor Spaces，通常称为 S0 和 S1）。
      - 老年代（Old Generation）：用于存放生命周期较长的对象。

2. 方法区（Method Area）（在 JDK 1.8 中已被细化为元空间 Metaspace）：
   - 用途：存储已被加载的类元数据、常量、静态变量等。在 JDK 1.8 中，用于取代永久代（PermGen）。
   - 元空间（Metaspace）：与永久代不同，元空间用的是本地内存而不是堆内存，这避免了 Java 中永久代容量不足导致的内存问题。

3. 栈（Stack）：
   - 用途：每个线程创建时会分配一个栈，它用来存储局部变量表、操作数栈、动态链接、方法出口等。栈内存会自动随着方法的进出而分配和释放。
   - 特性：栈是线程私有的，每个线程都有自己的栈。

4. 程序计数器（Program Counter Register）：
   - 用途：是一个较小的内存空间，用于指示当前线程所执行的字节码的行号。
   - 特性：它是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区。

5. 本地方法栈（Native Method Stack）：
   - 用途：与 Java 栈类似，但它主要用于处理本地方法（Native Method）的执行。
   - 特性：也是线程私有的，负责本地方法的调度和执行。

这些内存区的设计是为了支持 Java 的垃圾收集机制和多线程并发运行，确保 Java 应用程序能够高效和稳定地执行。了解这些内存区的功能和作用，可以帮助开发者优化 Java 应用的性能，并有效管理内存使用。

#### 4.1.2 垃圾回收算法

GC 核心在于通过不同的算法来高效管理内存资源。常用的 GC 算法包括：

1. 标记-清除算法（Mark and Sweep）：
   - 标记阶段：遍历所有的对象引用，标记活动的对象。
   - 清除阶段：清理掉未被标记的对象。
   - 缺点：容易造成内存碎片，因为清除后内存是不连续的。

2. 复制算法（Copying）：
   - 将活动的对象从一块内存（From space）复制到另一块（To space），然后清理整块 From space。
   - 优点：内存分配简单，不会产生碎片。
   - 缺点：需要预留多余的内存空间实行复制。

3. 标记-整理算法（Mark-Compact）：
   - 标记阶段：和标记-清除相似。
   - 整理阶段：将所有活动对象移到一端，处理剩余的空间为可用。
   - 减少了碎片化问题，但相比复制算法更复杂。

4. 分代收集算法：
   - 根据对象的生命周期不同，将堆分为新生代和老年代。
   - 新生代使用复制算法，老年代使用标记-清除 或 标记-整理。
   - 优点：优化了大多数对象短命这一特性带来的效率。垃圾回收算法。

#### 4.1.3 垃圾收集器

Java 提供了多种垃圾收集器，适用于不同应用场景：

1. Serial GC：
   - 单线程收集器，非常适合单线程环境和小型应用。
   - 效率高但可能造成长时间的停顿。

2. Parallel GC (Throughput Collector)：
   - 多线程收集器，用于最大化 CPU 吞吐量。
   - 适合后台处理任务和高效利用系统资源的场景。

3. CMS GC (Concurrent Mark-Sweep Collector)：
   - 重点在于缩短停顿时间，适合响应时间敏感的应用。
   - 较轻量级的 GC，但处理老年代垃圾时效率不如 Parallel。

4. G1 GC (Garbage-First Collector)：
   - 设计用于大堆，提供可预测的停顿时间。
   - 将堆划分为不同的区域（Region），针对不同老化级别进行回收。

5. ZGC / Shenandoah GC：
   - 尝试实现低延迟垃圾回收，几乎不会造成任何长时间的停顿。

#### 4.1.4 code_cache (代码缓存区)、compressed_class_space (压缩类空间)、metaspace (元空间)，他们的用途是什么，有什么要注意的。

在 Java 虚拟机（JVM）中，非堆内存部分包括多个区域，每个区域负责存储不同种类的数据，这里重点介绍 Code Cache（代码缓存区）、Compressed Class Space（压缩类空间）和 Metaspace（元空间）的用途及注意事项。

##### 1. Code Cache（代码缓存区）

用途：
- JIT 编译代码：Java 虚拟机的即时编译器（Just-In-Time Compiler，JIT）会将频繁使用的字节码编译成本地机器码，以提高运行性能。编译后的本地代码存储在代码缓存区中。
- 性能提升：通过存储这些编译后的代码，JVM 可以避免对同一代码片段重复进行解释，从而提升执行速度。

注意事项：
- 内存限制：代码缓存区有固定的最大值（可通过 `-XX:ReservedCodeCacheSize` 参数配置），需要注意在长时间运行的应用程序中这个区不会被耗尽，否则可能导致性能退化。
- 清理与优化：JVM 在启动时和运行过程中可能会执行代码缓存的清理和优化，这个过程会对性能有一定影响。

##### 2. Compressed Class Space（压缩类空间）

用途：
- 存储类元数据：在开启类指针压缩的情况下（默认开启），这个空间用于存储类元数据的压缩指针，以节省内存空间。
- 支持元空间：压缩类空间是元空间的一部分，专门用来优化类加载器的内存消耗。

注意事项：
- 有固定最大限制：虽然是元空间的一部分，但压缩类空间有自己的最大内存限制（默认为 1GB），可以通过 `-XX:CompressedClassSpaceSize` 参数调整。
- 适配性告诉：32 位 JVM 不使用压缩类空间功能，64 位 JVM 在默认情况下是开启的，因其节省的内存对大型应用尤其重要。

##### 3. Metaspace（元空间）

用途：
- 替换永久代：Java 8 开始，用元空间替代了永久代，用于存储类的元数据（类的结构信息、方法、字段等）。
- 动态调整大小：与永久代不同，元空间作为物理内存的一部分，不断增长（直到达到物理内存上限），默认不设置上限，灵活性更高。

注意事项：
- 内存泄漏风险：尽管更灵活，但如果不加限制，糟糕的类加载策略可能导致元空间内存泄漏。在开发环境中尤其要防止过度类加载。
- 调整与监控：可以通过 `-XX:MetaspaceSize` 和 `-XX:MaxMetaspaceSize` 进行调节，适当限制，在实际使用中密切监控。
- 自动释放：JVM 在内存不足时会尝试回收未使用的类加载的内存，虽然一般无需手动干预，了解这方面的配置有助于优化内存使用。

这些部分的配置和监控是调优 JVM 的重要组成部分，适当的配置可以防止内存泄漏、排查性能瓶颈，并为应用程序的稳定性提供保障。

### 4.2 火焰图

#### 4.2.1 生成脚本

profiler 命令支持生成应用热点的火焰图。本质上是通过不断的采样，然后把收集到的采样结果生成火焰图。火焰图可以清楚的看到程序运行中对象的创建，这样你就可以发现那些大对虾(像)从哪来的？

操作过程，开启采集 `profiler start --event alloc` 等待程序执行，关闭采集 `profiler stop --format html`

我们操作中，开启采集后，可以先执行多次的 curl-one.sh 调用接口，多产生点对象。

```java
profiler start --event alloc

profiler getSamples

profiler status

profiler stop --format html
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-07.png" width="650px">
</div>

- 执行完成后，你会得到一个火焰图的 html 文件。之后就可以打开了。

#### 4.2.2 查看图表

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-08.png" width="950px">
</div>

1. 这里的x轴代表采样总量（也就是此刻所有执行的耗时cpu的方法）。这是注意的是x 轴并不代表时间，而是所有的调用方法合并后，按字母顺序排列。
2. Y轴代表方法的调用栈深度，每一层都是一个方法。顶部是正在执行的方法。当然调用栈越深，火焰就越高。
3. 鼠标可以点击的选中的每个框就代表了一个栈里的函数，其宽度可以直接理解为CPU时间占比（其实是采样的数量以及与采样总量的占比）。
4. 那么，也就是说占比比较宽的框就表示：a.该函数运行时间较长（单次时间长）b.被调用次数较多.（调用频率高）进而被采样的次数比较多，占用的CPU时间多。
4. 这样你就知道了是哪里在创建大对像。比如一些数据库对象，缓存对象等，特别大，又耗时，一下就监控出来了。

> Arthas 提供的功能还有很多，不过咱们要换个更加舒服的方式使用了。如下。

## 五、IDEA Plugin Arthas

### 1. 安装插件

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-09.png" width="950px">
</div>

### 2. 使用插件

这些命令你都可以通过 Arthas IDEA Plugin 插件复制出来使用。

- [monitor](https://arthas.aliyun.com/doc/monitor.html) - 方法执行监控
- [stack](https://arthas.aliyun.com/doc/stack.html) - 输出当前方法被调用的调用路径
- [trace](https://arthas.aliyun.com/doc/trace.html) - 方法内部调用路径，并输出方法路径上的每个节点上耗时
- [tt](https://arthas.aliyun.com/doc/tt.html) - 方法执行数据的时空隧道，记录下指定方法每次调用的入参和返回信息，并能对这些不同的时间下调用进行观测
- [watch](https://arthas.aliyun.com/doc/watch.html) - 方法执行数据观测

更多命令 [https://arthas.aliyun.com/doc/commands.html](https://arthas.aliyun.com/doc/commands.html)

#### 2.1 复制命令

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-10.png" width="950px">
</div>

#### 2.2 使用命令

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-11.png" width="950px">
</div>

- 如图你就可以监控到方法的运行信息了。

### 3. 其他命令

#### 3.1 查看代码

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-12.png" width="950px">
</div>

- 线上运行的代码，不确定是否是最新的，那么这样就可以一步获取到并对比。

#### 3.2 接口参数

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-arthas-13.png" width="950px">
</div>

- 有时候预发验证服务，因为不会打印所有的服务接口出入参信息，但遇到问题不好排查。
- 那么使用 Arthas 插件，就可以直接获取到接口的出入参了，方便排查问题。

> 其他更多命令可以通过官网的命令提示和插件一起使用验证了。

---

### Md Road Map Buddy (`docs/md/road-map/buddy.md`)

---
title: Docker 镜像构建 - Buddy
lock: need
---

# Docker 镜像构建 - Buddy

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

2c2g 云服务器，你占用了83%的内存空间！**傅哥！Jenkins 用不起呀！** 我好不容易找对象要50块买的一年服务器，要学你的项目。现在都被 Jenkins 吃了！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-03.png?raw=true" width="200px">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-01.gif?raw=true" width="200px">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-02.png?raw=true" width="200px">
</div>

哈哈哈，最近一段时间跟 `CI&CD` 工具杠上了，一路调研和尝试体验了 Jenkins、GitLab、Drone、CircleCI、TeamCity、Bamboo、Travis CI、Codeship、GoCD、Wercker、Semaphore、Nevercode、Spinnaker、Buildbot... 等十多款风格迥异的构建部署工具。可以说 Jenkins 依旧是当家老大。所以小傅哥的第一篇 `CI&CD` 文章则是[《用上了 Jenkins，个人部署项目是真方便！》](https://mp.weixin.qq.com/s/tWuse0ejDOTQho2182iYWw) 但这货也确实是嘎嘎占内存！

为此，小傅哥今天分享另外一款，轻量、简单、好用，还好看的在线 `CI&CD` 工具。直接点点点，配置下就能使用了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-04.png?raw=true" width="800px">
</div>

咋样，这款工具看着不错吧。它叫 [buddy.works](https://buddy.red/) 是一款付费软件，但提供了免费白皮袄的额度。足够我们个人用户使用。

>本文会向小伙伴介绍这块工具的使用操作，方便小白们快速上手。在文末还提供了Java项目学习，让小白从实战中积累变成经验。

## 一、工具相关

- 官网(中文)：[https://buddy.red](https://buddy.red)
- 文档(中文)：[https://docs.buddy.red](https://docs.buddy.red)
- 官网(英文)：[https://buddy.works](https://buddy.works)

这款工具号称 **「最易用的CI/CD没有之一」**，体验过后我表示，他说的对！

## 二、注册账户

地址：[https://buddy.works/sign-up?locale=cn&utm_campaign=buddy.red](https://buddy.works/sign-up?locale=cn&utm_campaign=buddy.red)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-05.png?raw=true" width="450px">
</div>

## 三、添加项目

地址：[https://app.buddy.works/](https://app.buddy.works/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-06.png?raw=true" width="750px">
</div>

- 首先，需要在首页选择【添加项目】，并根据步骤选择你的仓库。
- 之后，这里小傅哥选择了专用服务器，填写我的Gitcode仓库地址。「Gitcode的账密就是CSDN的账密」
- 提示：你可以Fork代码到自己的仓库进行使用 [https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins) 

## 四、添加流水线

流水线，就跟它的名字一样，用于构建项目所需的一条链路流程。如；Maven 构建、镜像打包&发布、SSH 基本驱动容器启动。也可以是 Maven 构建后直接通过 SFTP 把Jar传递到 Linux 服务器，在通过 SSH 链接执行 Shell 脚本完成 Jar 的镜像打包和部署。

所以，接下来我们先来完成一个流水线的最基础 Maven 构建，之后再分别添加不同类型的流水线操作。「Buddy提供了各种插件，你可以分别组合他们进行使用，完成项目的部署。」

注意📢：流水线上的节点，你可以在右侧的绿色按钮进行关闭，只执行你需要的节点。比如现在你已经知道 Maven 构建成功了，只需要推送镜像。那么可以去掉上一个节点，这样速度更快。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-07.png?raw=true" width="750px">
</div>

### 1. Docker 流水线

- 说明：这条流水线的步骤为；Maven 构建、构建Docker镜像、推送Docker镜像、SSH连接服务器拉取镜像和部署。
- 步骤：你可以点击**小加号+**，选择添加不同的流水线节点。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-08.png?raw=true" width="750px">
</div>

#### 1.1 构建Docker镜像

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-09.png?raw=true" width="750px">
</div>

#### 1.2 推送Docker镜像

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-10.png?raw=true" width="750px">
</div>

- 注意📢：你已经在 [https://hub.docker.com/](https://hub.docker.com/) 创建了自己的镜像，比如我的是；[fuzhengwei/xfg-dev-tech-jenkins](fuzhengwei/xfg-dev-tech-jenkins) 这样你的镜像才能PUSH进去。

#### 1.3 SSH连接服务器拉取镜像和部署

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-11.png?raw=true" width="750px">
</div>

```shell
# 先删除之前的容器和镜像文件
if [ "$(docker ps -a | grep xfg-dev-tech-jenkins)" ]; then
docker stop xfg-dev-tech-jenkins
docker rm xfg-dev-tech-jenkins
fi
if [ "$(docker images -q xfg-dev-tech-jenkins)" ]; then
docker rmi xfg-dev-tech-jenkins
fi

docker pull fuzhengwei/xfg-dev-tech-jenkins:2.0
docker run -itd -p 8091:8091 --name xfg-dev-tech-jenkins fuzhengwei/xfg-dev-tech-jenkins:2.0
```

- 注意：拉取镜像的速度取决于你的服务器所在的地区，有时候会拉取失败。如果你的云服务器拉取镜像总是失败❌，可以选择第二个方式 SSH 流水线。它不需要走到DockerHub，能减少网络操作。

### 2. SSH 流水线

说明：这条流水线的步骤为；Maven构建、通过 SFTP 上传构建的Jar到云服务器。之后通过 SSH 执行 Shell 脚本，在云服务器创建出 Dockerfile 「注意路径」，这样 Docker镜像就直接在云服务器的 Docker上了，不需要在通过 DockerHub 拉取镜像。最后通过 SSH 执行 Shell 脚本启动服务即可。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-12.png?raw=true" width="750px">
</div>

#### 2.1 SFTP 上传Jar

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-13.png?raw=true" width="750px">
</div>

- 配置好传输地址、目标地址，通过 SSH 连接云服务器进行传输。
- `/dev-ops`这个是云服务器的地址，你可以自己定义任何的地址。如果文件夹不存在，也会自动创建。

#### 2.2 创建Dockerfile

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-14.png?raw=true" width="750px">
</div>

```shell
#!/bin/bash

cd /dev-ops

# 定义Dockerfile的路径
DOCKERFILE_PATH="https://bugstack.cn/images/roadmap/tutorial/Dockerfile"
    
# 创建Dockerfile并写入内容
cat > $DOCKERFILE_PATH << 'EOF'
# 基础镜像 openjdk:8-jre-slim
FROM openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用
ADD target/xfg-dev-tech-app.jar /xfg-dev-tech-app.jar

## 在镜像运行为容器后执行的命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /xfg-dev-tech-app.jar $PARAMS"]
EOF

echo "Dockerfile has been created."
```

- 因为我们把 Maven 构建的 Jar 传到了云服务器。所以需要在 Jar 对应的目录下，创建出 Dockerfile 这样就可以通过执行 Dockerfile 完成镜像的构建了。
- 此外如果你的代码库配置有 Dockerfile，也可以通过 SFTP 的方式把 Dockerfile 上传到云服务器对应 Jar 的位置。「我只是帮你选择了一个更稳的方式」

#### 2.3 运行服务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-15.png?raw=true" width="750px">
</div>

```shell
# 先删除之前的容器和镜像文件
if [ "$(docker ps -a | grep xfg-dev-tech-jenkins)" ]; then
docker stop xfg-dev-tech-jenkins
docker rm xfg-dev-tech-jenkins
fi
if [ "$(docker images -q xfg-dev-tech-jenkins)" ]; then
docker rmi xfg-dev-tech-jenkins
fi

cd /dev-ops
docker build -t xiaofuge/xfg-dev-tech-jenkins:1.3 .
docker run -itd -p 8091:8091 --name xfg-dev-tech-jenkins xiaofuge/xfg-dev-tech-jenkins:1.3
```

- `cd /dev-ops`进入到文件路径。之后构建镜像和部署。

## 五、运行流水线

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-buddy-16.png?raw=true" width="750px">
</div>

- 点击**运行**，就可以顺序的执行你的配置的流水线了。如果某个执行失败也可以重试。
- 如果你执行完成3个节点，最后一个失败。那么是可以把前面的流程关闭，只去验证最后一个流程。这样会更快。

>怎么样，是不是很方便。但要注意，https://app.buddy.works - 账单中，会记录你的免费额度。

---

### Md Road Map Cainiao (`docs/md/road-map/cainiao.md`)

---
title: 菜鸟教程 - 交互式学习
lock: need
---

# 菜鸟教程 - 交互式学习

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

一直以来我都有一个想法，做一套更符合新人上手学习的 **🐦菜鸟教程**，以在线互动交互的方式学习入门编程技术。

但原本`互动交互`这东西太耗前端能力了，好在，现在有大量的 Ai Agent 工具，帮我我把想法落地了！—— 我有创新和内容，Ai Agent 出设计和效果！嘎嘎舒服！**美美桑内，一个劲叭叭！**

<div align="center">
    <img src="https://bugstack.cn/images/article/project/chatgpt/chatgpt-extra-230905-01.png?raw=true" width="150px">
</div>

**这是一个什么样的教程？**

小傅哥做的教程分为3大类，一类是带着做**实战项目**（拼团、大营销、技术组件等）、一类是**编程路书**（系统架构、开发技术、发布部署等），现在再准备开启一项更基础的，辅助刚入门的小白来学习编程技能。

这套教程，专门为小白设计，包括；环境配置（Mac、Windows）、`SpringBoot`、`MyBatis`、`Redis`、`Mysql`、`Maven` 等各项编程技术的入门讲解。后续还会继续迭代新的课程进去。

本套教程不只是干巴巴的讲技术，而是做了学习互动，你可以看到如 SpringBoot 课程下模拟的在线 IntelliJ IDEA 打开教程代码，还可以看到 Dev-Ops 云服务器操作时候的互动过程。这样的学习，即使是小白，也可以很好理解自己在做什么，为什么做。

## 一、能学到啥

此套教程，以入门编程为主，让小卡拉米和小菜鸟，快速补充基础技术知识。全套教程，会以目前最新的环境配置、技术框架、编程技巧等为本，设计基础入门教程。包括；

- 【框架】22节课程，SpringBoot 入门教程，涵盖；环境搭建与项目初始化、核心概念与配置管理、数据库集成与容器管理、高级特性与性能优化、测试与监控管理、企业级应用特性。
- 【运维】Dev-Ops 云服务器操作，一键安装脚本、云服务器 SSH 模拟（学习命令）、本地环境 + 云服务器，配置、构建、上线，学习环境基础使用。
- 【环境】基于 Apache Maven 3.8.9 版本编写，涵盖了 Maven 的核心概念、配置和实际应用。
- 【后端】MySQL 从基础到高级，掌握 MySQL 数据库开发与管理，完整覆盖 MySQL 基础到高级概念，详细对比 MySQL 5.7 与 8.x 版本差异，涵盖性能优化和高级特性。
- 【后端】Redis 教程，从入门到精通的完整学习指南。学习 Redis 的核心概念和高性能特性，掌握字符串、哈希、列表、集合等数据类型。

> 以上内容，已更新完成 SpringBoot、Dev-Ops 部分，其他内容也更新了目录，后续详细更新内容。

## 二、课程展示

**课程地址**：[https://gaga.plus/](https://gaga.plus/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cainiao-01.png" width="550px">
</div>

你可以进入到 gaga.plus，之后点击菜鸟教程，开启你的入门编程之旅！

### 1. 课程目录

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cainiao-02.png" width="750px">
</div>

### 2. 教程举例 - SpringBoot

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cainiao-03.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cainiao-04.png" width="750px">
</div>

- 进入教程，学习章节内容。还可以在线看，模拟 IntelliJ IDEA 打开的工程代码。非常方便学习。

### 3. 教程举例 - Dev-Ops

#### 3.1 云服务器连接

地址：[https://gaga.plus/app/dev-ops/tutorials/what-is-a-cloud-server.html](https://gaga.plus/app/dev-ops/tutorials/what-is-a-cloud-server.html)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-02.png" width="850px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-03.png" width="850px">
</div>

#### 3.2 云服务器使用

地址：[https://gaga.plus/app/dev-ops/tutorials/cloud-server-dev-ops.html](https://gaga.plus/app/dev-ops/tutorials/cloud-server-dev-ops.html)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cainiao-05.png" width="750px">
</div>

- 你可以点击各个按钮【本地环境搭建、Linux服务器配置、SSH远程连接、本地开发连接、代码部署（1、2）】，这样可以动态的看到各个演示环节。
- 此外，你可以在 SSH 连接后，基于提供的命令教程进行学习。

好啦，如果你还有什么样的基础内容学习诉求，可以在评论区留言，我会优先进行开发上线！

---

### Md Road Map Canal (`docs/md/road-map/canal.md`)

---
title: Canal
lock: need
---

# 通过MySQL binlog日志，使用canal同步分库分表数据，到 Elasticsearch

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=1902486427&bvid=BV1Gm411r7kz&cid=1484158643&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，配置出一套 Canal 工具服务，来同步分库分表的数据到 Elasticsearch 文件夹系统中。同时在 SpringBoot 工程中，配置出两套数据源，一套是 MySQL + MyBatis，一套是 Elasticsearch + MyBatis。【这是非常重要的设计手段】

虽然现在有 TiDB 这样的分布式数据库，但对于分库分表 + 数据同步ES，依然是非常主流的方案。同时也有一部分是把分库分表的数据同步到 TiDB 使用。

本文涉及的工程：

- xfg-dev-tech-canal：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-canal](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-canal)
- docs/dev-ops/xfg-dev-tech-canal-docker-compose.yml：提供了所需的环境安装，mysql、canal-server、canal-adapter、elasticsearch、kibana
- Github：[https://github.com/alibaba/canal](https://github.com/alibaba/canal)

## 一、组件介绍

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-01.png" width="750px">
</div>

canal ，译为水道/管道/沟渠，主要用途是基于 MySQL 数据库增量日志解析，提供增量数据订阅和消费。

早期阿里巴巴因为杭州和美国双机房部署，存在跨机房同步的业务需求，实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始，业务逐步尝试数据库日志解析获取增量变更进行同步，由此衍生出了大量的数据库增量订阅和消费业务。

它的工作原理是，canal 模拟 MySQL slave 的交互协议，伪装自己为 MySQL slave ，向 MySQL master 发送dump 协议。在 MySQL master 收到 dump 请求，开始推送 binary log 给 slave (即 canal ) 这样 canal 再解析 binary log （binlog）进行配置分发，同步到 Elasticsearch 等系统中进行使用。

那么有了 canal 就可以把分库分表的数据同步到 Elasticsearch，提供汇总查询和聚合操作，也就不需要把轮训每个分库分表数据了。

## 二、测试预期

本文的案例会把MySQL，2库4表的数据，通过 Sharding 分库分表写入数据后，同步到 Elasticsearch。分库分表如下（环境安装中会自动安装数据库和设置库表）；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-06.png" width="750px">
</div>

## 三、环境安装

为了让读者伙伴更加简单的学习到这一项方案技能，小傅哥这里把所需的环境都配置成一整套的 docker compose 脚本文件（ARM、AMD），你只要执行安装即可。安全前注意，无论是本机还是云服务器都需要安装 [docker-ce](https://bugstack.cn/md/road-map/docker.html)

### 1. 环境脚本

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-02.png" width="950px">
</div>

- 打开 xfg-dev-tech-canal 工程，下面就是 docker compose 的执行脚本。
- mac/windows 如果安装了 docker 可以直接点击如图的三角号安装。如果是在 Linux 安装了 docker 可以把 dev-ops 整个文件夹都上传到云服务器，之后通过脚本；`docker-compose -f xfg-dev-tech-canal-docker-compose.yml up -d` 进行安装。

#### 1.1 开启 binlog

mysql 数据同步需要创建一个 canal 的账户，之后还需要开启 binlog 日志

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-07.png" width="950px">
</div>

- 在 mysql 配置文件夹中，设置了初始化授权的账户、导入的库表，以及开启 mysql-bin 和配置要采集的库。
- 如果你有配置自己其他的库要同步也可以如此配置。

#### 1.2 库表采集配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-08.png" width="950px">
</div>

- 本文选择的是 es 同步方式，所以需要在 canal-adapter 中 es7 文件夹添加同步的库表 yml 配置。
- 以及在 application.yml 中配置出需要链接的库表以及同步的目标地址，也就是 es 的地址。【因为本文的案例是在同一个 docker compose 下安装，所以直接用名称 elsticsearch 即可访问】

### 2. 运行状态

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-03.png" width="950px">
</div>

- 安装完成后可以进入 portainer 查看各个组件的运行，如果有哪个运行失败了，可以点击那个小文件的图标，它可以查看日志。

### 3. 创建索引

在 doc/dev-ops/curl 下提供了创建 Elasticsearch 的脚本；你可以点击执行或者直接复制执行，也可以复制导入到 ApiPost 里执行。

以上这些脚本是为了创建出数据库表同步到 Elasticsearch 后对应的索引和映射的字段。文章下面会用到。

#### 3.1 创建

```shell
curl -X PUT "127.0.0.1:9200/xfg_dev_tech.user_order" -H 'Content-Type: application/json' -d'
{
    "mappings": {
      "properties": {
        "_user_id":{"type": "text"},
        "_user_name":{"type": "text"},
        "_order_id":{"type": "text"},
        "_uuid":{"type": "text"},
        "_create_time":{"type": "date"},
        "_update_time":{"type": "date"}
      }
    }
}'
```

#### 3.2 添加

```shell
curl -X PUT "127.0.0.1:9200/xfg_dev_tech.user_order/_mapping" -H 'Content-Type: application/json' -d'
{
  "properties": {
    "_sku_name": {
      "type": "text"
    }
  }
}'
```

#### 3.3 删除

```shell
curl -X DELETE "127.0.0.1:9200/xfg_dev_tech.user_order"
```

### 4. 创建索引（Kibana）

#### 4.1 索引管理

**地址**：[http://127.0.0.1:5601/app/management/kibana/indexPatterns](http://127.0.0.1:5601/app/management/kibana/indexPatterns)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-04.png" width="950px">
</div>

- 填写完，点击创建索引模式即可。

#### 4.2 数据页面

**地址**：[http://127.0.0.1:5601/app/discover](http://127.0.0.1:5601/app/discover)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-05.png" width="750px">
</div>

- 等后面同步数据了以后，直接在这里点刷新就可以看到了。

### 5. 许可证

kibana 提供了免费30天的试用许可，安装后可以使用 x-pack-sql-jdbc。它的好处是可以让我们通过 MyBatis 的方式查询 Elasticsearch 数据。

**地址**：[http://127.0.0.1:5601/app/management/stack/license_management](http://127.0.0.1:5601/app/management/stack/license_management)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-09.png" width="750px">
</div>

Elasticsearch 提供了 x-pack-sql-jdbc，让对 Elasticsearch 的查询也可以像使用 MySQL 数据库一样通过 MyBatis 进行查询。但这个 x-pack-sql-jdbc 是付费的，免费可以使用 30 天。之后你可以选择使用重新安装，破解，或者使用 Elasticsearch 的查询方式。还可以自己开发一个 Elasticsearch JDBC，GitHub 上也有类似的组件。

使用时需要引入 POM 配置；

```pom

<dependency>
    <groupId>org.elasticsearch.plugin</groupId>
    <artifactId>x-pack-sql-jdbc</artifactId>
    <version>7.17.14</version>
</dependency>
```

## 三、工程配置

本节涉及到了简明教程中所讲解的 [Sharding 分库分表](https://bugstack.cn/md/road-map/sharding-jdbc.html)的使用，因为我们需要把分库分表的数据通过 canal 同步到 Elasticsearch。（也可以使用其他分库分表组件）

在工程中配置一套 Sharding 分库分表映射的 MyBatis MyBatis，在配置一套 Elasticsearch x-pack-sql-jdbc 数据源映射的 MyBatis Mapper。这样可以读写分别走自己设定好的 Mapper 对象了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-10.png" width="950px">
</div>

### 1. 创建数据源

```
/* Detailed source-code truncated for AI context efficiency. */
```

- ElasticsearchMyBatisConfig 使用 EsDataSource 创建数据源和映射 MyBatis Mapper 文件。
- MysqlMyBatisConfig 使用 DataSourceBuilder 创建 Sharding 提供的数据源和映射 MyBatis Mapper 文件。

### 2. Mapper 映射

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.xfg.dev.tech.infrastructure.dao.elasticsearch.IElasticsearchUserOrderDao">

    <resultMap id="dataMap" type="cn.bugstack.xfg.dev.tech.infrastructure.po.UserOrderPO">
        <result column="_user_id" property="userId"/>
        <result column="_user_name" property="userName"/>
        <result column="_order_id" property="orderId"/>
        <result column="_sku_name" property="skuName"/>
        <result column="_update_time" property="updateTime"/>
        <result column="_create_time" property="createTime"/>
    </resultMap>

    <select id="selectByUserId" resultMap="dataMap">
        select _user_id, _user_name, _order_id, _sku_name
        from "xfg_dev_tech.user_order"
        order by _update_time
        limit 10
    </select>

</mapper>
```

这个是 Elasticsearch 映射的 Mapper 文件，映射的字段就是前面安装环境的时候设置的索引和字段。现在你使用 Elasticsearch 就不用在工程中硬编码查询语句了，变得非常方便。

## 四、工程测试

### 1. 写入数据

```java
@Test
public void test_insert() throws InterruptedException {
    for (int i = 0; i < 3; i++) {
        UserOrderPO userOrderPO = UserOrderPO.builder()
                .userName("小傅哥")
                .userId("xfg_" + RandomStringUtils.randomAlphabetic(6))
                .userMobile("+86 13521408***")
                .sku("13811216")
                .skuName("《手写MyBatis：渐进式源码实践》")
                .orderId(RandomStringUtils.randomNumeric(11))
                .quantity(1)
                .unitPrice(BigDecimal.valueOf(128))
                .discountAmount(BigDecimal.valueOf(50))
                .tax(BigDecimal.ZERO)
                .totalAmount(BigDecimal.valueOf(78))
                .orderDate(new Date())
                .orderStatus(0)
                .isDelete(0)
                .uuid(UUID.randomUUID().toString().replace("-", ""))
                .ipv4("127.0.0.1")
                .ipv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334".getBytes())
                .extData("{\"device\": {\"machine\": \"IPhone 14 Pro\", \"location\": \"shanghai\"}}")
                .build();
        userOrderDao.insert(userOrderPO);
        Thread.sleep(100);
    }
}
```

- 循环插入3条数据，按需你可以设置更多条数据。
- 这里的用户编号 userId 是随机的，也是切分键的 ID，所以会在不同的库表写入数据。

### 2. 数据验证

- MySQL：[http://127.0.0.1:8899/](http://127.0.0.1:8899/) docker compose 配置的管理后台，可以 root/123456 登录
- Kibana：[http://127.0.0.1:5601/app/discover](http://127.0.0.1:5601/app/discover) 查询写入的数据。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-11.png" width="950px">
</div>

### 3. 查询数据

```java
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserOrderDaoTest {

    @Resource
    private IElasticsearchUserOrderDao userOrderDao;

    @Test
    public void test() {
        List<UserOrderPO> userOrderPOS = userOrderDao.selectByUserId();
        log.info("测试结果：{}", JSON.toJSONString(userOrderPOS));
    }

}
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-canal-12.png" width="950px">
</div>

- 通过 Elasticsearch 走 x-pack-sql-jdbc 的方式再把数据查询出来。

---

### Md Road Map Cloud Server (`docs/md/road-map/cloud-server.md`)

---
title: CloudServer 云服务器是什么？
lock: need
---

# CloudServer 云服务器是什么？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

可以这么说，云服务器的使用，是每个程序员在编程路上的必备技能。因为我们所有开发的代码，最终都将部署到云服务器运行，为用户提供运算能力。包括；`京东`、`淘宝`、`拼多多`、`滴滴`、`美团`，他们的服务，都是在云服务器上运行。**不过，你会使用云服务器吗？🤔**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-00.png" width="150px">
</div>

**你是否对云服务器比较陌生？**

其实不少伙伴没怎么使用过云服务器，一方面是因为没有意识到项目最终是在云服务器部署（也没有主动虚席），另一方面是因为云服务器基本是使用 Linux 系统，不像是 Windows/Mac 电脑一样，基本是没有图形化界面的，所以对于云服务器的使用就有了一道**障碍**。

不过，鉴于云服务器的技能这么重要。所以，小傅哥准备做一套基础的**免费教程**，来教会小白伙伴上手云服务器使用。这套教程，通过在线网站提供图形化界面 + 模拟体验的方式，教会小白伙伴上手云服务器。

> 📢 本套课程，是小傅哥多年的沉淀的经验，转化最易接受和上手学习的方式，让小白伙伴可以轻松的掌握全套关于云服务器的知识和实践运用。

## 一、课程地址

**地址**：[https://gaga.plus/](https://gaga.plus/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-01.png" width="650px">
</div>

> 如图，教程地址，会陆续更新在线课程。可以收藏地址，关注后续课程更新（更新内容会在公众号「bugstack虫洞栈」发布通知）。

## 二、我能学到什么？

通过这套教程，你可以完成的理解云服务器的用途，掌握云服务器的操作技能。从零基础到熟练运用云服务器 + 本地环境完成项目的开发、测试和部署的全流程。教程采用在线演示体验，互动式学习方式，以及一键安装的脚本，让复杂的云服务器操作，变得简单和易于理解。

- 🏗️理解云服务器的概念、选择、配置、管理，以及通过 shell 脚本，完成自动化的初始化环境操作。
- ☕ 在云服务器部署 Git、Java、Maven 环境，可以通过云服务器完成项目的构建。
- 🐳 Docker 容器化技术，完成项目的构建镜像、操作部署等。
- 🔐 远程连接与安全，学习 SSH 链接云服务器和 Linux 命令操作云服务器。
- 🌿 版本控制与协作，可以在云服务器通过 Git 检出项目进行维护使用。
- 🚀 部署与运维，以代码开发、Git Push、Git Pull、mvn clean install、docker，一些列命令，完成项目的打包和上线。

这套教程的特色在于完全可视化学习，注重理论与实践，不仅让您了解云服务器的基本概念，更重要的是通过交互式演示和自动化脚本，让您能够快速上手并在实际项目中应用这些技术。无论您是初学者还是有一定经验的开发者，都能从中获得有价值的知识和技能提升。

## 三、小傅哥为你准备了什么？

小傅哥，今天为你准备了第一套在线教程**《第1节：云服务器，是什么？》**

在这套教程，你可以直接直观的理解到云服务器相对于本地电脑，其实就等同于你的另外一个电脑而已。并且，小傅哥这里做了模拟的链接，**你可以在线体验通过 SSH 连接云服务器，并执行 Linux 脚本运行**。关于这些写脚本，已经写好了相关的执行动作和说明，很适合小白伙伴学习使用。

### 1. 云服务器链接

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-02.png" width="850px">
</div>

- 首先，云服务器，就是你在互联网上的另一台电脑，随时随地访问使用，任意安装和卸载软件。尤其对软件学习来说，可以避免windows电脑的兼容问题。
- 之后，你可以点击建立 SSH 链接，这个时候会弹出 SSH 链接操作。让你真的的体验到如何通过 SSH 链接云服务器。

### 2. Linux 命令模拟

#### 2.1 建立链接（SSH）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-05.png" width="450px">
</div>

- 如图，IP、用户名、密码、端口号，就是你在获得一个云服务器后，可以拿到的连接信息。在你真实使用云服务器时，也是需要获得这些信息进行连接操作。
- 之后，通过点击建立SSH连接，模拟登录云服务器。**没有云服务器的伙伴，也能随时体验云服务器操作**

#### 2.2 体验登录

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-03.png" width="850px">
</div>

- 我知道很多小伙伴，不太熟悉 Linux 命令。所以，小傅哥这里做了模拟操作，你可以点击命令，之后就可以看到执行结果，以及告诉你命令的用途。此外还有 Git、Maven、Docker 常见命令的学习。
- 通过这套东西的学习，对于云服务器的使用，基本就可以有一个操作的使用认知了。后续在看到要执行命令，也都能理解，是怎么的一个操作过程。

#### 2.3 常用命令

**如下，这些命令都已经加入到体验区 👨🏻‍💻**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-cloud-server-04.png" width="400px">
</div>

- 你可以点击各个命令，学习对应的场景用途。
- 如果，小伙伴还有其他命令想学习，也可以留言。我会进行补充。

> 后续，还有更炸裂的在线模拟学习课，让你身临其境的学习云服务器的操作。我们下一节再见👋🏻

---

### Md Road Map Connection Pool (`docs/md/road-map/connection-pool.md`)

---
title: ConnectionPool
lock: need
---

# MySQL 连接池 c3p0、dbcp、druid、hikari

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=362541635&bvid=BV1a94y1r7bP&cid=1241367723&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式，向读者展示 SpringBoot 应用程序对接 MySQL 时，在使用不同连接池以及不使用连接池时，在增删改查的一个性能对比。这也包括更新和查询时，索引字段的关键性。

内容开始之前，你知道1张21个字段的表，存放100万数据，大于会占用多少空间容量吗？如果这100万数据在不使用连接池的方式，10个并发一条条插入，要多少时间？

问题1需要`350M`左右、问题2需要`2-3`小时。可能你会说，这字段不一定都多长，这插入不知道的机器配置。但其实这些并不是重要的，如果你做过一次你肯定能说出自己一个所在机器配置下的数据验证结果。而本文则借着对 MySQL 连接池的 ApacheBench 压测验证，让读者伙伴可以学习到相关的知识。

本文涉及的工程：

- xfg-dev-tech-connection-pool：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-connection-pool](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-connection-pool) - 工程内含有环境的安装脚本；`mysql-docker-compose.yml`、`apachebench-docker-compose.yml`、`road_map_8.0.sql` 

## 一、案例背景

`拿100万订单数据，压到数据库中！`

本章节小傅哥会带着大家初始化一个空的数据库表，并向数据库表中写入100万数据。之后在分别不使用`连接池`和使用不同的连接池(c3p0、dbcp、druid、hikari)写入数据，测试各个连接池的性能。这也能让大家知道，日常我们应该选择哪个连接池。

## 二、环境配置

因为本章节很偏实操，所以需要大家做下提前安装好 Docker 环境，以便于执行本章节工程中的脚本和代码。可参考Java简明教程系列内容 Docker、Portainer 学习安装和使用。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-connection-pool-01.png?raw=true" width="850px">
</div>

- 在 IntelliJ IDEA 打开 xfg-dev-tech-connection-pool 分别点开 mysql-docker-compose、apachebench-docker-compose，之后点击安装即可。
- 执行完脚本，你可以得到一份安装好的 MySQL 8.0 并安装了数据库表。另外一份是用于压测使用的 [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html)
- 连接 MySQL 的工具，推荐使用开源免费的 [Sequel Ace](https://apps.apple.com/us/app/sequel-ace/id1518036000?ls=1)

## 三、工程说明

在 xfg-dev-tech-connection-pool 工程中提供了不同连接池的配置和一些非常常用的 SQL 操作，以及提供了对应的接口进行压测使用；

| 序号 | 接口                                                         | 说明                                               |
| ---- | ------------------------------------------------------------ | -------------------------------------------------- |
| 1    | http://127.0.0.1:8091/api/mysql/cacheData                    | 用于缓存数据的接口，拿缓存好的数据压测更新、查询   |
| 2    | http://127.0.0.1:8091/api/mysql/insert                       | 插入数据接口                                       |
| 3    | http://127.0.0.1:8091/api/mysql/updateOrderStatusByUserId    | 使用索引字段 userId 更新订单状态                   |
| 4    | http://127.0.0.1:8091/api/mysql/updateOrderStatusByUserMobile | 使用无索引字段 userMobile 更新订单状态             |
| 5    | http://127.0.0.1:8091/api/mysql/updateOrderStatusByOrderId   | 使用索引字段 orderId 更新订单状态                  |
| 6    | http://127.0.0.1:8091/api/mysql/selectByUserId               | 使用索引字段 userId 查询订单                       |
| 7    | http://127.0.0.1:8091/api/mysql/selectByUserMobile           | 使用无索引字段 userMobile 查询订单，测试中添加索引 |
| 8    | http://127.0.0.1:8091/api/mysql/selectByOrderId              | 使用有索引字段 orderId 查询订单                    |
| 9    | http://127.0.0.1:8091/api/mysql/selectByOrderIdAndUserId     | 区分度高的索引字段在前，区分度低的索引字段在后     |
| 10   | http://127.0.0.1:8091/api/mysql/selectByUserIdAndOrderId     | 区分度低的索引字段在前，区分度高的索引字段在后     |

- 具体代码实现可以直接对照工程来看，以及按需添加SQL语句进行性能压测验证。

## 四、库表语句

SQL：`xfg-dev-tech-connection-pool/docs/sql/road_map_8.0.sql`

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-connection-pool-02.png?raw=true" width="850px">
</div>

- 这是本节所需要测试的一个订单表和测试前所建的索引字段。以及初始化了100万数据，占用350M空间。
- 接下来，我们就可以做测试验证了。

## 五、压测指令

ApacheBench 官网教程：[https://httpd.apache.org/docs/2.4/programs/ab.html](https://httpd.apache.org/docs/2.4/programs/ab.html)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-connection-pool-03.png?raw=true" width="850px">
</div>

常用的如：`ab -c 20 -n 1000 http://127.0.0.1:8091/hi` - 20个并发1000次

## 六、压测验证

首先在测试前，正式测试前，你大概需要花费几十分钟来初始化100万数据。执行脚本；`ab -c 20 -n 1000000 http://127.0.0.1:8091/api/mysql/insert` - 如果你在工程中配置了 no-pool 大概要花费几个小时才能跑完，这就使用和不使用连接池的差距。

### 1. 连接池比对

**条件**；

1. 插入1万条数据
2. 连接池配置 initialPoolSize=5、minPoolSize=5、maxPoolSize=20
2. 此时数据库已经有100万数据，分别用几个链接方式插入数据。hikari 放到最后，它是 SpringBoot 的默认连接池。
2. 脚本；`ab -c 20 -n 10000 http://127.0.0.1:8091/api/mysql/insert`

|      |    no-pool     |      c3p0      |      dbcp      |     druid      |     hikari     |
| :--: | :------------: | :------------: | :------------: | :------------: | :------------: |
| 耗时 | 88.990 seconds | 24.228 seconds | 33.656 seconds | 25.971 seconds | 25.002 seconds |
| 50%  |     155ms      |      39ms      |      60ms      |      45ms      |      43ms      |
| 80%  |     223ms      |      61ms      |      86ms      |      64ms      |      64ms      |
| 90%  |     291ms      |      75ms      |     103ms      |      75ms      |      76ms      |

- 通过对比可以发现，如果不使用连接池，会比使用连接池，要占用更多的时间连接数据库使用数据库。
- c3p0、hikari 的性能还是非常不错的，dbcp 相对是弱一些的。所以这可以给你在使用连接池时有一个参考。也可以结合你的机器再次进行压测验证。

### 2. 更新对比

**条件**；

1. 使用接口，向内存加入600条数据。每个测试方式，分别消耗200条。`ab -c 10 -n 600 http://127.0.0.1:8091/api/mysql/cacheData`
2. 之后使用无索引字段、有索引但区分度不高的字段以及使用有索引区分度非常好的字段来更新。
3. 脚本；
   1. `ab -c 20 -n 200 http://127.0.0.1:8091/api/mysql/updateOrderStatusByUserMobile`
   2. `ab -c 20 -n 200 http://127.0.0.1:8091/api/mysql/updateOrderStatusByUserId`
   3. `ab -c 20 -n 200 http://127.0.0.1:8091/api/mysql/updateOrderStatusByOrderId`


|      | 无索引  | 有索引-区分度不高 | 有索引-区分度很高 |
| :--: | :-----: | :---------------: | :---------------: |
| 耗时 | 24小时+ |      24小时+      |   0.432 seconds   |
| 50%  | 24小时+ |      24小时+      |       35ms        |
| 80%  | 24小时+ |      24小时+      |       48ms        |
| 90%  | 24小时+ |      24小时+      |       67ms        |

- 无索引的时候；会把整个表的这个记录，全部锁上。那么越执行越慢，最后拖垮数据库。甚至可能1天都执行不完。
- 有索引-区分度不高；几乎是一样的，如果你批量的对一个用户的所有数据都更新，也会锁很多记录。
- 有索引-区分度很高；只要你锁的是自己的一条记录，就与别人没有影响。效率也会非常高。

### 3. 查询对比

**条件**；

1. 查询100万加的数据库表记录，每次缓存记录5000条数据id；`ab -c 10 -n 5000 http://127.0.0.1:8091/api/mysql/cacheData`
2. userId 有索引、orderId 有索引、userMobie 无索引。
2. 每次查询的时候，都要关闭服务重启，避免有缓存干扰结果。
3. 脚本：
   1. `ab -c 20 -n 5000 http://127.0.0.1:8091/api/mysql/selectByUserMobile`
   2. `ab -c 20 -n 5000 http://127.0.0.1:8091/api/mysql/selectByUserId`
   3. `ab -c 20 -n 5000 http://127.0.0.1:8091/api/mysql/selectByOrderId`
   4. `ab -c 20 -n 5000 http://127.0.0.1:8091/api/mysql/selectByOrderIdAndUserId`
   5. `ab -c 20 -n 5000 http://127.0.0.1:8091/api/mysql/selectByUserIdAndOrderId`

|      | 无索引 | 有索引-区分度不高 | 有索引区分度高 |    高在前     |    低在前     |
| ---- | :----: | :---------------: | :------------: | :-----------: | :-----------: |
| 耗时 | 6小时+ |   8.343 seconds   | 2.051 seconds  | 2.168 seconds | 3.279 seconds |
| 50%  |   7s   |       13ms        |      7ms       |      7ms      |     11ms      |
| 80%  |   9s   |       20ms        |      10ms      |     11ms      |     17ms      |
| 90%  |  15s   |       26ms        |      13ms      |     13ms      |     22ms      |

- 无索引，还是查询字段的。非常危险。
- 不要在一些区分度不高的字段建索引。当然本案例中，userId 最多也就1000来个用户所产生的1百万数据，这样的情况更适合分库分表。
- 区分度很高的字段，查询效率会非常好。
- 把高区分度的索引字段放在前面，更有利于查询。—— 注意不要测试完上一个，直接测试下一个。有缓存的情况下，会影响对比结果。

---

这就是整个数据库表的压测过程了。如果你有使用的诉求，需要做技术调研，那么一定要做一些这样的压测处理。这样有真实数据才好讲道理。另外需要面试的伙伴，你不是总没有数据吗，来吧，按照这个压一压！

---

### Md Road Map Db Router (`docs/md/road-map/db-router.md`)

---
title: db-router
lock: need
---

# 数据库分库分表路由组件

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=911880460&bvid=BV1fM4y1e7xe&cid=1152400081&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，如何实现一个分库分表的路由组件。这里包括；AOP、路由散列算法、动态数据源切换等相关知识。

本文涉及的工程：

- xfg-dev-tech-db-router：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-db-router](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-db-router) 

## 一、需求分析

`如果要做一个数据库路由，都需要做什么技术点？`

首先我们要知道为什么要用分库分表，其实就是由于业务体量较大，数据增长较快，所以需要把用户数据拆分到不同的库表中去，减轻数据库压力。

分库分表操作主要有垂直拆分和水平拆分：
- 垂直拆分：指按照业务将表进行分类，分布到不同的数据库上，这样也就将数据的压力分担到不同的库上面。最终一个数据库由很多表的构成，每个表对应着不同的业务，也就是专库专用。
- 水平拆分：如果垂直拆分后遇到单机瓶颈，可以使用水平拆分。相对于垂直拆分的区别是：垂直拆分是把不同的表拆到不同的数据库中，而水平拆分是把同一个表拆到不同的数据库中。如：user_001、user_002

而本章节我们要实现的也是水平拆分的路由设计，如图 1-1



那么，这样的一个数据库路由设计要包括哪些技术知识点呢？

- 是关于 AOP 切面拦截的使用，这是因为需要给使用数据库路由的方法做上标记，便于处理分库分表逻辑。
- 数据源的切换操作，既然有分库那么就会涉及在多个数据源间进行链接切换，以便把数据分配给不同的数据库。
- 数据库表寻址操作，一条数据分配到哪个数据库，哪张表，都需要进行索引计算。在方法调用的过程中最终通过 ThreadLocal 记录。
- 为了能让数据均匀的分配到不同的库表中去，还需要考虑如何进行数据散列的操作，不能分库分表后，让数据都集中在某个库的某个表，这样就失去了分库分表的意义。

综上，可以看到在数据库和表的数据结构下完成数据存放，我需要用到的技术包括：`AOP`、`数据源切换`、`散列算法`、`哈希寻址`、`ThreadLoca`l以及`SpringBoot的Starter开发方式`等技术。而像`哈希散列`、`寻址`、`数据存放`，其实这样的技术与 HashMap 有太多相似之处，**那么学完源码造火箭的机会来了** 如果你有过深入分析和学习过 HashMap 源码、Spring 源码、中间件开发，那么在设计这样的数据库路由组件时一定会有很多思路的出来。*接下来我们一起尝试下从源码学习到造火箭！*

## 二、技术调研

在 JDK 源码中，包含的数据结构设计有：数组、链表、队列、栈、红黑树，具体的实现有 ArrayList、LinkedList、Queue、Stack，而这些在数据存放都是顺序存储，并没有用到哈希索引的方式进行处理。而 HashMap、ThreadLocal，两个功能则用了哈希索引、散列算法以及在数据膨胀时候的拉链寻址和开放寻址，所以我们要分析和借鉴的也会集中在这两个功能上。

### 1. ThreadLocal



```java
@Test
public void test_idx() {
    int hashCode = 0;
    for (int i = 0; i < 16; i++) {
        hashCode = i * 0x61c88647 + 0x61c88647;
        int idx = hashCode & 15;
        System.out.println("斐波那契散列：" + idx + " 普通散列：" + (String.valueOf(i).hashCode() & 15));
    }
} 

斐波那契散列：7 普通散列：0
斐波那契散列：14 普通散列：1
斐波那契散列：5 普通散列：2
斐波那契散列：12 普通散列：3
斐波那契散列：3 普通散列：4
斐波那契散列：10 普通散列：5
斐波那契散列：1 普通散列：6
斐波那契散列：8 普通散列：7
斐波那契散列：15 普通散列：8
斐波那契散列：6 普通散列：9
斐波那契散列：13 普通散列：15
斐波那契散列：4 普通散列：0
斐波那契散列：11 普通散列：1
斐波那契散列：2 普通散列：2
斐波那契散列：9 普通散列：3
斐波那契散列：0 普通散列：4
```

- **数据结构**：散列表的数组结构
- **散列算法**：斐波那契（Fibonacci）散列法
- **寻址方式**：Fibonacci 散列法可以让数据更加分散，在发生数据碰撞时进行开放寻址，从碰撞节点向后寻找位置进行存放元素。公式：`f(k) = ((k * 2654435769) >> X) << Y对于常见的32位整数而言，也就是 f(k) = (k * 2654435769) >> 28 `，黄金分割点：`(√5 - 1) / 2 = 0.6180339887` `1.618:1 == 1:0.618`
- **学到什么**：可以参考寻址方式和散列算法，但这种数据结构与要设计实现作用到数据库上的结构相差较大，不过 ThreadLocal 可以用于存放和传递数据索引信息。

### 2. HashMap



```java
public static int disturbHashIdx(String key, int size) {
    return (size - 1) & (key.hashCode() ^ (key.hashCode() >>> 16));
}
```

- **数据结构**：哈希桶数组 + 链表 + 红黑树
- **散列算法**：扰动函数、哈希索引，可以让数据更加散列的分布
- **寻址方式**：通过拉链寻址的方式解决数据碰撞，数据存放时会进行索引地址，遇到碰撞产生数据链表，在一定容量超过8个元素进行扩容或者树化。
- **学到什么**：可以把散列算法、寻址方式都运用到数据库路由的设计实现中，还有整个数组+链表的方式其实库+表的方式也有类似之处。

## 三、设计实现

### 1. 定义路由注解

**定义**

```java 
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface DBRouter {

    String key() default "";

}
```

**使用**

```java
@Mapper
public interface IUserDao {

     @DBRouter(key = "userId")
     User queryUserInfoByUserId(User req);

     @DBRouter(key = "userId")
     void insertUser(User req);

}
```

- 首先我们需要自定义一个注解，用于放置在需要被数据库路由的方法上。
- 它的使用方式是通过方法配置注解，就可以被我们指定的 AOP 切面进行拦截，拦截后进行相应的数据库路由计算和判断，并切换到相应的操作数据源上。

### 2. 解析路由配置



- 以上就是我们实现完数据库路由组件后的一个数据源配置，在分库分表下的数据源使用中，都需要支持多数据源的信息配置，这样才能满足不同需求的扩展。
- 对于这种自定义较大的信息配置，就需要使用到 `org.springframework.context.EnvironmentAware` 接口，来获取配置文件并提取需要的配置信息。

**数据源配置提取**

```java
@Override
public void setEnvironment(Environment environment) {
    String prefix = "router.jdbc.datasource.";    

    dbCount = Integer.valueOf(environment.getProperty(prefix + "dbCount"));
    tbCount = Integer.valueOf(environment.getProperty(prefix + "tbCount"));    

    String dataSources = environment.getProperty(prefix + "list");
    for (String dbInfo : dataSources.split(",")) {
        Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, prefix + dbInfo, Map.class);
        dataSourceMap.put(dbInfo, dataSourceProps);
    }
}
```

- prefix，是数据源配置的开头信息，你可以自定义需要的开头内容。
- dbCount、tbCount、dataSources、dataSourceProps，都是对配置信息的提取，并存放到 dataSourceMap 中便于后续使用。

### 3. 数据源切换

在结合 SpringBoot 开发的 Starter 中，需要提供一个 DataSource 的实例化对象，那么这个对象我们就放在 DataSourceAutoConfig 来实现，并且这里提供的数据源是可以动态变换的，也就是支持动态切换数据源。

**创建数据源**

```java
@Bean
public DataSource dataSource() {
    // 创建数据源
    Map<Object, Object> targetDataSources = new HashMap<>();
    for (String dbInfo : dataSourceMap.keySet()) {
        Map<String, Object> objMap = dataSourceMap.get(dbInfo);
        targetDataSources.put(dbInfo, new DriverManagerDataSource(objMap.get("url").toString(), objMap.get("username").toString(), objMap.get("password").toString()));
    }     

    // 设置数据源
    DynamicDataSource dynamicDataSource = new DynamicDataSource();
    dynamicDataSource.setTargetDataSources(targetDataSources);
    return dynamicDataSource;
}
```

- 这里是一个简化的创建案例，把基于从配置信息中读取到的数据源信息，进行实例化创建。
- 数据源创建完成后存放到 `DynamicDataSource` 中，它是一个继承了 AbstractRoutingDataSource 的实现类，这个类里可以存放和读取相应的具体调用的数据源信息。

### 4. 切面拦截

在 AOP 的切面拦截中需要完成；数据库路由计算、扰动函数加强散列、计算库表索引、设置到 ThreadLocal 传递数据源，整体案例代码如下：

```java
@Around("aopPoint() && @annotation(dbRouter)")
public Object doRouter(ProceedingJoinPoint jp, DBRouter dbRouter) throws Throwable {
    String dbKey = dbRouter.key();
    if (StringUtils.isBlank(dbKey)) throw new RuntimeException("annotation DBRouter key is null！");

    // 计算路由
    String dbKeyAttr = getAttrValue(dbKey, jp.getArgs());
    int size = dbRouterConfig.getDbCount() * dbRouterConfig.getTbCount();

    // 扰动函数
    int idx = (size - 1) & (dbKeyAttr.hashCode() ^ (dbKeyAttr.hashCode() >>> 16));

    // 库表索引
    int dbIdx = idx / dbRouterConfig.getTbCount() + 1;
    int tbIdx = idx - dbRouterConfig.getTbCount() * (dbIdx - 1);   

    // 设置到 ThreadLocal
    DBContextHolder.setDBKey(String.format("%02d", dbIdx));
    DBContextHolder.setTBKey(String.format("%02d", tbIdx));
    logger.info("数据库路由 method：{} dbIdx：{} tbIdx：{}", getMethod(jp).getName(), dbIdx, tbIdx);
   
    // 返回结果
    try {
        return jp.proceed();
    } finally {
        DBContextHolder.clearDBKey();
        DBContextHolder.clearTBKey();
    }
}
```

- 简化的核心逻辑实现代码如上，首先我们提取了库表乘积的数量，把它当成 HashMap 一样的长度进行使用。
- 接下来使用和 HashMap 一样的扰动函数逻辑，让数据分散的更加散列。
- 当计算完总长度上的一个索引位置后，还需要把这个位置折算到库表中，看看总体长度的索引因为落到哪个库哪个表。
- 最后是把这个计算的索引信息存放到 ThreadLocal 中，用于传递在方法调用过程中可以提取到索引信息。

## 四. 测试验证

### 1. 库表创建

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 创建相同表结构的多个库存信息，bugstack_01、bugstack_02

### 2. 语句配置

```java
<select id="queryUserInfoByUserId" parameterType="cn.bugstack.middleware.test.infrastructure.po.User"
        resultType="cn.bugstack.middleware.test.infrastructure.po.User">
    SELECT id, userId, userNickName, userHead, userPassword, createTime
    FROM user_${tbIdx}
    where userId = #{userId}
</select>               

<insert id="insertUser" parameterType="cn.bugstack.middleware.test.infrastructure.po.User">
    insert into user_${tbIdx} (id, userId, userNickName, userHead, userPassword,createTime, updateTime)
    values (#{id},#{userId},#{userNickName},#{userHead},#{userPassword},now(),now())
</insert>
```

- 在 MyBatis 的语句使用上，唯一变化的需要在表名后面添加一个占位符，`${tbIdx}` 用于写入当前的表ID。

### 3. 注解配置

```java
@DBRouter(key = "userId")
User queryUserInfoByUserId(User req);   

@DBRouter(key = "userId")
void insertUser(User req);
```

- 在需要使用分库分表的方法上添加注解，添加注解后这个方法就会被 AOP 切面管理。

### 4. 单元测试

```java
22:38:20.067  INFO 19900 --- [           main] c.b.m.db.router.DBRouterJoinPoint        : 数据库路由 method：queryUserInfoByUserId dbIdx：2 tbIdx：3
22:38:20.594  INFO 19900 --- [           main] cn.bugstack.middleware.test.ApiTest      : 测试结果：{"createTime":1615908803000,"id":2,"userHead":"01_50","userId":"980765512","userNickName":"小傅哥","userPassword":"123456"}
22:38:20.620  INFO 19900 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'1

```

- 以上就是我们使用自己的数据库路由组件执行时的一个日志信息，可以看到这里包含了路由操作，在2库3表：`数据库路由 method：queryUserInfoByUserId dbIdx：2 tbIdx：3`

---

### Md Road Map Ddd Archetype Maven (`docs/md/road-map/ddd-archetype-maven.md`)

---
title: DDD 脚手架【Maven 在线版】
lock: need
---

# 我把DDD脚手架，发布到了Maven仓库，大家都能用了！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=1151660636&bvid=BV1yZ42187zo&cid=1468150515&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主，小傅哥。

这篇文章将帮助粉丝伙伴们更高效地利用小傅哥构建的`DDD（领域驱动设计）脚手架`，搭建工程项目，增强使用的便捷性。让👬🏻兄弟们直接在 IntelliJ IDEA 配置个在线的链接，就能直接用上这款脚手架！——  **你就说猛不猛！🤨**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-01.png" width="850px">
</div>

- 配置地址 https://gaga.plus - `备用地址：[https://maven.xiaofuge.cn](https://maven.xiaofuge.cn)`
- ddd-scaffold-lite 提供了默认版本和 v2 版本。v2 做了少量调整。将 repository、port 统一归属到 adapter 下管理。

---

**那小傅哥搞的这个在线版脚手架是怎么做到的呢？** 🤔 想学吗，想学我教你呀？

在23年的时候小傅哥发布了 DDD 两款脚手架，一个轻量版 lite ，一个标准版 std。通过这两款脚手架，小伙伴们在学习小傅哥写的技术教程和实战项目的时候，可以把脚手架代码下载到本地，通过 `maven install` 在本地构建出脚手架再配置到上图中的地址后使用。

我的理想情况是大家都能很顺利的构建、配置，美滋滋的使用，但实际情况却是，编码的路上，错误是层出不穷！

所以，我动手了。我要为你们提供更Easy的方式！但也差点难住我。接下来我就给伙伴们分享下，这个东西是如何搞的。

>文末有8个实战项目，可以加入学习。🉐 项目：[https://gaga.plus](https://gaga.plus)

## 一、思考的开始 🤔

我发布过自己的 IntelliJ IDEA vo2dto 到插件市场，也推送过 openai sdk、chatglm sdk、db-router 等组件到 Maven 中央仓库。

那我就寻思了，这脚手架也是个 Jar 包，应该也能发布到 Maven 中央仓库呀。要不Maven Central 自己那个脚手架是怎么发上去的？在编程开发这个事上，我一直秉承着，只要我能看见的，就都应该能复刻出来。

但你知道这里有一点，发布到 Maven 仓库的是 Jar 包，那我配置脚手架的地址哪里来呢（地址里是脚手架的定义）？我应该也没办法把脚手架的定义推送到人家 maven.apache.org 下面去。毕竟那是人家的老巢。如果能推送，那我现在打开的 Maven Central 应该有一堆脚手架，而不只是 Maven Central 所发布自己的。

所以，我灵机一动😁，打开了 [https://repo.maven.apache.org/maven2](https://repo.maven.apache.org/maven2)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-02.png" width="550px">
</div>

这个 `archetype-catalog.xml` 就是在构建 Maven 项目的脚手架时所产生的脚手架定义文件，配置到 IntelliJ IDEA 中，才会展示出脚手架列表，并可以选择使用。

那我知道了，虽然我不能推送到 maven 的老巢里去。但我可以自己提供个地址呀，把 `archetype-catalog.xml` 推送进去。经过最开始的验证，确实可以，完全没问题！Easy！

但接下来的问题变得麻烦了，Jar 怎么推送到 Maven 仓库呢。**傅哥，你不是推过吗，你咋不行了？** 死鬼！tnnd，推送 Jar 到 Maven 仓库从24年2月改版了！！！全编程界的鸡鸭鹅狗🦆，都没有人发过教程！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-03.png" width="550px">
</div>

因为这个推送 Jar 在最开始的两天时间里，我一度怀疑是自己超限额了，不能创建了。也曾想过要不就只推送到 阿里云的私有仓库吧，大家配置个 阿里云 Maven 镜像地址，也能用。但这样的情况始终觉得不爽🙅🙅🏻‍，所以我走上了研究新版推送 Jar 的方式，直至最终成功啦💐！！！舒服！

>接下来我就给小伙伴们分享下，这东西是怎么推送上去的。

## 二、觉得我也行 🤨

### 1. 卡卡两脚

做一个新的技术东西之前呢，先要检索下资料，看看有啥坑不。这个阶段也叫技术调研。卡卡一定能搜 `发布Jar到maven仓库`，全是以前的旧版本方案，没有一个能用的！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-04.png" width="550px">
</div>

还有一个我写的，卡卡上去给两脚！不行了，确实没啥关于新版上传 Jar 到 Maven 仓库的资料，自己去趟坑吧。

### 2. 冒烟测试

完成目标最快的方式是什么？兄弟们！当然是结果驱动，先干一脚，看它嚎不嚎。遇到问题再解决问题。所以我准备先无脑上传一波，看看都给我什么信息。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-05.png" width="550px">
</div>

- 地址：[https://central.sonatype.com/publishing](https://central.sonatype.com/publishing)
- 看着这个上传组件的小图，还挺简单的。不过在这里它是一句有用的话都不写。那我就写个名字和上传个Jar进去。*心里笑嘻嘻，难度，它会根据我的 Jar 自动分析 POM？*

但发现我想多了，第一次上传全是报错！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-06.png" width="650px">
</div>

- 什么 pom 文件没传。所以我又机智的把 Jar 和 POM 打包了 zip 上传。
- 紧接着报错 `Invalid 'md5' checksum for file: scaffold-lite-1.0-sources.jar`，缺少 md5、sha1 验证。好在我以前发布过 maven 仓库，知道这些配置。
- 基本上知道要怎么传了，接下来，细看文档。遇到什么类错误，优先看什么内容。

### 3. 操作步骤

在 [https://central.sonatype.com/publishing](https://central.sonatype.com/publishing) 首页有一个 Help 帮助文档，[https://central.sonatype.org/register/central-portal/#producers](https://central.sonatype.org/register/central-portal/#producers) 这里有非常详细的操作说明。接下来我讲一些核心的步骤，如果操作有失败，可以参考官网资料。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-07.png" width="650px">
</div>

开始前，登录注册 [https://central.sonatype.com](https://central.sonatype.com) - 可以选择 github 登录。

#### 3.1 配置 NameSpace

如果选择 github 登录，你会有一个默认配置的 NameSpace（io.github.fuzhengwei），这个东西的作用就是要和本地工程名 groupId 保持一致的。如工程是 cn.bugstack、plus.gaga、com.liergou，那么你在的 NameSpace 就需要配置一个这样的调过来的域名。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-08.png" width="650px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-09.png" width="650px">
</div>

- 如图配置完添加验证即可，最后验证成功就可以使用了。

#### 3.2 上传要求

文档：[https://central.sonatype.org/publish/publish-portal-upload/](https://central.sonatype.org/publish/publish-portal-upload/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-10.png" width="750px">
</div>

- 如文档上传要求，你需要把jar、pom、doc、sources 全部打包到 zip 包，同时每个文件的 asc、md5、sha1 也需要打包进来。
- 这些文件也都是在旧版上传 maven 中央仓库的时候，所需提供的内容。

#### 3.3 项目配置

**源码**：[https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-lite/-/tree/master/scaffold-lite](https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-lite/-/tree/master/scaffold-lite)

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 注意 groupId、artifactId 名字，如果你有发布诉求，需要和你自己的一致。
- maven-javadoc-plugin：生成 doc 文档。这里要注意，因为我们脚手架不是代码文件，没有doc的，所以要在工程中加一个任意类名文件。工程中小傅哥加了个 Api 类。
- maven-source-plugin：生成 source 文件。
- maven-gpg-plugin：是签名的加密文件，需要本地安装过 gpg 包。注意；`checksum-maven-plugin` 需要在 `maven-gpg-plugin` 执行，这样就不用做下面的手动 md5 逻辑了。
- checksum-maven-plugin：生成 md5、sha1 文件，但这里不会对 pom 生成此文件，还需要单独命令处理。

```shell
md5 ddd-scaffold-lite-1.0.pom > ddd-scaffold-lite-1.0.pom.md5
shasum ddd-scaffold-lite-1.0.pom > ddd-scaffold-lite-1.0.pom.sha1
```

- 检查生成后的文件，去掉不需要的内容。

#### 3.4 构建项目

**第1次构建**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-11.png" width="750px">
</div>

**第2次构建**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-12.png" width="750px">
</div>

**执行脚本**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-13.png" width="750px">
</div>

#### 3.5 上传 archetype-catalog.xml

把 archetype-catalog.xml 文件，上传到域名可访问云服务器的根目录中。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-14.png" width="350px">
</div>

#### 3.6 上传打包文件到 maven 仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-15.png" width="950px">
</div>

- 你需要按照你的工程结构也是 namespace 创建出文件夹结构，并把工程 target 打包的文件全部复制进来。
- 最后把 io 这个文件夹，打包一个 zip 包。就可以了。

#### 3.7 上传 maven 仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-16.png" width="650px">
</div>

#### 3.8 成功啦！💐

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-17.png" width="650px">
</div>

好啦，这就是整个脚手架的操作过程！现在你可以体验使用了。

## 三、开始卷项目 🚴🏻

小傅哥是一个大厂的架构师，经常会带着伙伴们，卷这些实际场景中非常有必要的技术。也会带着伙伴实战项目，这些项目也都是来自于互联网大厂中真实的业务场景，所有学习这样的项目无论是实习、校招、社招，都是有非常强的竞争力。别人还在玩玩具，而你已经涨能力！

>🧧这样的项目学习在小傅哥星球「码农会锁」有8个，每个都是从0到1开发并提供简历模板和面试题，并且还在继续开发，后续还将有更多！价格嘎嘎实惠，早点加入，早点提升自己。项目地址：[https://gaga.plus](https://gaga.plus)

在星球学习中，你可以把项目组合使用。用业务的+技术的+组件的，会非常有竞争力。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-maven-archetype-18.png" width="950px">
</div>

---

### Md Road Map Ddd Archetype (`docs/md/road-map/ddd-archetype.md`)

---
title: DDD 脚手架【Maven 本地版】
lock: need
---

# DDD 工程脚手架 + 一键安装分布式技术栈环境！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=278113187&bvid=BV1Gw411u7Dz&cid=1322192636&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

写了那么多案例工程，开发了那么多技术项目。那小傅哥做的这些案例和项目是每一个都要手动创建一遍吗？🤔 如果不是一个个都手动创建，那么有什么提效工具吗？

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-01.gif?raw=true" width="150px">
</div>

不用，根本不用。因为小傅哥有一套**神器**！

对于 DDD 项目的多模块化工程搭建，其实真的是一个挺耗时的工作，尤其是分布式工程的搭建更是耗时。不过工程模块的创建还不算太耗时，主要耗时在各个分布式组件的整合使用上，包括：MySQL、Redis、RocketMQ、Dubbo、shardingjdbc、XXL-JOB 等一堆技术框架。如果你做过这样的事情，一定会被他们的使用和各类版本的配合，折腾过服服帖帖。

一次工程和环境搭建，没有个6~8小时都搞不完！但今天我想你动动手指就搞定这些！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-02.png?raw=true" width="600px">
</div>

那么，接下来小傅哥就介绍下这套带有配套环境安装的工程脚手架，让小伙伴可以熟悉使用，快速搭建自己的学习工程。

>文末有相关工程脚手架的获取地址，还有对应工程脚手架的学习项目。

## 一、效果展示

这是一套完整的工程级框架搭建标准，提供工程的脚手架搭建以及对应的完整环境初始化。可以让开发项目的伙伴，快速🔜完成基本工作，减少6~8小时的折腾。先来展示下整体教授的内容。

### 1. 工程框架

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-11.png?raw=true" width="750px">
</div>

### 2. 环境展示

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-12.png?raw=true" width="750px">
</div>

### 3. Redis 管理

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-13.png?raw=true" width="750px">
</div>

### 4. MySql 管理

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-14.png?raw=true" width="750px">
</div>

### 5. MQ 管理

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-15.png?raw=true" width="750px">
</div>

### 6. JOB 管理

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-16.png?raw=true" width="750px">
</div>

## 二、框架介绍

小傅哥这里提供了2套工程脚手架，一套轻量版的无任何分布式技术栈的使用，另外一套是标准版的全系使用分布式技术栈。因为很多小型项目并不需要依赖太多的分布式技术栈，而且轻量化的设计开发更能有效的提高开发效率。所以，读者可以按需选择你需要的脚手架进行学习、验证和生产。

### 1. 轻量版

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-03.png?raw=true" width="750px">
</div>

轻量版 DDD 框架，主要以提供 HTTP 服务为主。开发效率高，适合中小业务场景。
- 缓存，使用 Guava。如果有特定场景的情况下，可以补充 Redis 使用。
- 任务，使用 Quartz。
- 消息，使用 Spring/Guava 替代。

### 2. 标准版

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-04.png?raw=true" width="750px">
</div>

标准版 DDD 架构，以解决中大型场景业务开发为目的，综合使用分布式技术栈进行项目构建。
- Dubbo 提供 RPC 接口，Nacos 作为注册中心使用。
- Redis 提供缓存、加锁、数据处理服务。
- SharedingJdbc 提供分库分表服务。
- XXL-JOB 提供分布式任务调度服务。
- RocketMQ 提供异步消息服务。

## 三、使用说明

这套脚手架使用了 `maven-archetype-plugin` 使用命令(archetype:create-from-project)进行工程的脚手架创建，创建后再进行一些内容的修改，最终完成脚手架的模板。

读者在使用这套脚手架的时候，可以在本地下载工程代码后，进入工程下的 `scaffold-lite/std` 模块执行 README.md 中 `mvn clean install` 脚本进行安装。安装后即可在使用 IntelliJ IDEA 创建工程时候，选择 Maven 创建，添加本地仓库地址使用。—— 下面👇🏻会介绍具体操作步骤。

### 1. 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-05.png?raw=true" width="750px">
</div>

如图，就是两套 DDD 脚手架工程，每一套工程下，都有一个 scaffold 模块。这部分是对当下对应工程的脚手架模块。另外 docs 下有 dev-ops 文件夹，是环境安装包，直接执行 docker-compose.yml 即可一次安装完全部环境。

读者，在使用的时候，也可以先不看 scaffold 模块。因为除了这个模块外，其他的就是整个 DDD 工程，作为你最开始熟悉使用。熟悉后再进入“黑圈” README.md 中执行 mvc clean install 这样就能在本地 maven 仓库安装上脚手架了。

### 2. 框架安装

#### 2.1 安装

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-06.png?raw=true" width="750px">
</div>

- 进入工程脚手架模块下的 README.md 点击执行 mvn clean install

#### 2.2 配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-07.png?raw=true" width="750px">
</div>

- 首先是点击创建工厂，之后进入 Maven Archetype 下。
- 之后你需要自己配置好 maven 工程脚手架地址，有可能默认的路径地址，不生效。

#### 2.3 使用

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-08.png?raw=true" width="750px">
</div>

- 进入 Maven Archetype 如图方式创建工程。

#### 2.4 效果

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-09.png?raw=true" width="750px">
</div>

- 自动生成工程，之后你就可以通过 docs 文件夹下的 docker-compose.yml 安装环境并使用了。**注意本机已安装了 Docker**

### 3. 环境安装

文件：`docs/dev-ops/docker-compose.yml`

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-10.png?raw=true" width="950px">
</div>

- Mac 电脑安装 Docker 后，可以直接点击绿色的小按钮，一步安装所有配置好的环境。
- 云服务器，可以通过 `docker-compose -f docker-compose.yml up -d`进行安装。
- 资源访问；

  - 配置中心nacos：http://127.0.0.1:8848/nacos - 【账号：nacos 密码：nacos】
  - 消息rocketmq：http://127.0.0.1:8080/#/ - 【账号：admin 密码：admin】
  - 任务调度xxl-job-admin：http://127.0.0.1:9090/xxl-job-admin/ - 【账号：admin 密码：123456】
  - 缓存redis：http://127.0.0.1:8081/
  - 数据库MySQL：http://127.0.0.1:8899/ - 登录数据库信息，在线直接管理数据库

## 四、项目学习

有了工程脚手架，最好再有一套对应的实战项目学习。这样加起来锻炼，看看各个项目的模块都是如何调度的，才能更好的学习这套工程。而小傅哥的 **星球：码农会锁** 就有这样的项目锻炼，包括：OpenAi 应用项目、Lottery 抽奖项目、Api网关项目、IM通信项目、SpringBoot Starter 组件项目等。

>这样一套项目，放在一些平台售卖，至少都是几百块。但小傅哥的星球，只需要100多，就可以获得几千元的学习项目！

- 脚手架(轻量版)：[https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-lite](https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-lite)
- 脚手架(标准版)：[https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-std](https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-archetype-std)

>[🧧加入学习](https://bugstack.cn/md/zsxq/other/join.html)

在星球的实战项目中，都是以这样的企业级标准进行架构设计和落地，学习这样的项目就是学习公司的项目。—— 不做 CRUD 小项目，要做真的深度积累！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-17.png?raw=true" width="950px">
</div>

---

### Md Road Map Ddd Dev Account (`docs/md/road-map/ddd-dev-account.md`)

---
title: DDD 架构场景 - 账户域
lock: need
---

# 架构的本质之 DDD 架构 - 账户域

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=449298239&bvid=BV19j411b7uC&cid=1288675429&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

- 项目地址：[https://t.zsxq.com/14pbCR1IN](https://t.zsxq.com/14pbCR1IN)

---

### Md Road Map Ddd Dev Pay (`docs/md/road-map/ddd-dev-pay.md`)

---
title: DDD 架构场景 - 交易域
lock: need
---

# 架构的本质之 DDD 架构 - 交易域

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=234482923&bvid=BV1j8411k7C9&cid=1292535914&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

- 项目地址：[https://t.zsxq.com/14jRaQCvC](https://t.zsxq.com/14jRaQCvC)

---

### Md Road Map Ddd Guide 00 (`docs/md/road-map/ddd-guide-00.md`)

---
title: DDD 架构演进
lock: need
---

# DDD 架构演进，从单层、三层，四层，工程分层演进过程！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=116009398764656&bvid=BV1EJfRBNEdL&cid=35805267908&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

`定义接口`、`创建方法`、`调用展示`，其实编程写代码说到底也就这3步，人人都是程序员👨🏻‍💻。公司老板都觉得，它有个AI工具，它都能写代码。但现在的系统工程的分层结构，可不只是一层就写个 Controller，甚至是3层（Model-View-Controller），也有可能是4层（DDD）架构。这样的分层架构怎么理解呢？

<div align="center">
    <img src="https://bugstack.cn/images/system/zsxq/xingqiu-231018-00.png" width="200px">
</div>

**刚入行，直接就开大吗？**

在我最早接触编程的时候，还是9大内置对象，servlet、jsp、前端也是刚接触《锋利的JQuery》的时代。甚至很多流程代码都堆到了 jsp 页面，后端也就是连库做 CRUD 操作。多好的时代，学一点东西，就能上班赚钱了。现在要学的可就多了，仅专业技能部分，都能在写满简历 1/3 篇幅了！

但没办法，人嘛，总是要向钱低头的，向前！毕竟，互联网公司都是飞速迭代发展的，所以，要想混个能在群里喊【收到、收到】的资格，也得加倍学习。

所以，小傅哥就给大家分享下，关于系统分层架构的演进过程，看看这东西是怎么从简简单单变得复复杂杂的。

## 一、单层架构

单层架构并不算一个规范的架构定义，只是在早期 MVC 三层架构（模型、试图、控制器）还没有那么普及，以及国内开发的项目程序还没有那么规范的时候，用于快速搭建简单网页功能的一种设计。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-architectural-design-01.png" width="400px">
</div>

所有的分层结构的设计，都是以承接功能实现诉求为目的，这一阶段仅仅是完成网页的数据展示，也几乎没有用户交互。所以，很多时候是有多少个页面，就有多少个 Controller 提供接口，以及编写好调用数据库查询数据的操作。

## 二、三层架构

1978年，MVC模式最早由 [Trygve Reenskaug](https://zh.wikipedia.org/w/index.php?title=Trygve_Reenskaug&action=edit&redlink=1) 提出，**MVC模式**的目的是实现一种动态的程序设计，使后续对程序的修改和扩展简化，并且使程序某一部分的重复利用成为可能。除此之外，此模式透过对复杂度的简化，使程序结构更加直观。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-architectural-design-02.png" width="600px">
</div>

- 当 Controller 里承载业务功能逐步变多以后，我们开始思考怎么把这些东西分区存放。那么可以把各类对象归类到一个文件夹，之后把 Controller 里的复杂逻辑拆分为一个个原子的 service 服务，让 Controller 的接口负责调用。
- 目前的分层架构，就可以适合开发一些复杂逻辑的场景诉求了，不过整体系统的承载量仍然是偏弱一些的。

## 三、三层架构（分布式）

3层架构出现的很早，其实本身的设计没有考虑复杂的分布式场景。在从三层架构演变到可以支持分布式架构的时候，是没有一个统一的标准规范的，更多的各个公司里自己直接从旧工程里添加了新的 module 分层模块。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-architectural-design-03.png" width="600px">
</div>

- 首先，一个分布式架构要，对接 rpc、提供 rpc、消费 mq、生产 mq，还要做定时任务（最终一致性补偿），单一个 rpc 的使用，就需要在程序定义出一个 export 层，要打包对外的服务接口，让使用方式引入使用。关于为什么需要这样的方式，可以在 [bugstack.cn](https://bugstack.cn/md/road-map/dubbo.html) 编程路书中，开发技术部分 dubbo 学习。
- 之后，原本的 MVC 三层结构就不够用了。只要添加上，export、rpc 这样的分层，原本 service 直接处理数据库的操作，也要考虑拆分出来。可能这部分每个公司还不一样，其实即使一个公司，不同组，也是有很大的差异。这个也是目前互联网公司中的项目里的一个现状问题。
- 思考，现在的工程模型结构其实很杂，装填了太多的东西进去了。除此之外，因为都是原子化编写，没有在做分区。一个系统里 service 都有上千个类，每个类里又有上千行代码。在坐的各位，应该都会在这些屎山中赚钱。

## 四、四层架构

DDD 是思想，六边形/菱形/整洁架构是分层，DDD 通过建模思想，指导我们以从用例图（use case diagram）出发，与产品、研发、测试一起在一个规范下，脑暴建模。在这个过程中，以结果为导向，分析出可能存在的领域服务。这些领域服务，如登录完成，下单完成，支付完成，收货完成，根据结果态，分析支撑这样的服务所需的对象（实体）、流程、规则等。这样我们可以更加清晰的构建一套系统。

而，六边形（常用的）架构，则是用于承接 DDD 领域驱动设计对系统分析后的编码实现。六边形可以说是专门为 DDD 做的配套架构，虽然也可以用 MVC 来编写，但这样是会失去面向对象设计和编码的优势，让代码逻辑混乱在一起。所以，这也是各个互联网公司开始往 DDD 架构切换的目的。这件事，我已经干了好几年了！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-architectural-design-04.png" width="600px">
</div>

- 首先，六边形架构，以 DDD 领域驱动实际为指引，为 domai 层，设计充血模型结构，如；登录、下单、支付，在每个模块下，包含完整的服务、模型、适配。适配的目的是这个领域里所需的数据，都通过适配的方式从外部调用进来，比如；数据库、缓存、接口等。这是一种 ACL 防腐设计，将来外部的接口变化了，也不会影响我们的领域服务，只要按照领域服务的适配标准提供即可。
- 之后，围绕着领域 domain 开始，需要啥就让外部的基础设施层实现领域层的接口来提供。而接口要提供啥能力，就调用 case 编排 domain 层，或则简单的由 domain 层直接提供也可以。
- 最后，也就是 trigger 触发器，我们把接口、任务、mq等都理解为一种触发，之后让 trigger 调用 case 层。case 或者 domain 的目的，就是分摊 trigger 以前 Controller 编写逻辑代码的压力。让 trigger 只是负责对外逻辑的封装，错误码，异常即可。

综上，就是关于架构分层的一个演进过程，现在还有 AI 的加入，AI 也会逐步成为整个工程架构中的一块。关于这部分的架构设计，与业务工程的结合，小傅哥也会在 bugstack.cn 博客中陆续更新。

---

### Md Road Map Ddd Guide 01 (`docs/md/road-map/ddd-guide-01.md`)

---
title: DDD 概念理论
lock: need
---

# DDD 是什么？—— 你以前只会用 Service + 贫血模型！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1056091126&bvid=BV1oH4y1w7mN&cid=1610478439&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

DDD 是什么，这应该是每个想使用 DDD 开发项目的研发伙伴，遇到的第一个疑问，只有搞清楚它到底是什么才好上手使用。而 DDD 既不是 MVC 一样的工程结构，也不能直接等同于微服务架构，更不是一种设计模式。

## 1. DDD 是什么

那 DDD 是什么呢？来自于维基百科的一段定义：["Domain-driven design (DDD) is a major software design approach. "](https://en.wikipedia.org/wiki/Domain-driven_design)，DDD 是一种软件设计方法。也就是说 DDD 是指导我们做软件工程设计的一种手段，它提供了用切割工程模型的各类技巧，如；领域、界限上下文、实体、值对象、聚合、工厂、仓储等。通过 DDD 的指导思想，我们可以在前期投入更多的时间，更加合理的规划出可持续迭代的工程设计。

在 DDD 中有一套共识的工程两阶段设计手段，包括；战略设计、战术设计。

- **战略设计**，主要以应对复杂的业务需求，通过抽象、分治的过程，合理的拆分为独立的多个微服务，从而分而治之。与之评价拆分的是否合理，则是在需求开发上线时候，是否每次都大量操作多个微服务开发和上线。这样的战略设计是一种失败的微服务单体设计。所以少数几个中等规模的单体应用，周围环绕着一个服务生态系统，这更有意义。[你实际上并没有构建微服务 @贾斯汀·埃瑟里奇](https://www.simplethread.com/youre-not-actually-building-microservices/)

- **战术设计**，在这个范畴下，主要以讨论如何基于面向对象思维，运用领域模型来表达业务概念。通常在不做领域模型设计的架构，也就是通常映射到 MVC 三层架构下，`Service + 数据模型`的开发模式，会让 Service 扁平的、大量的，平铺出非常复杂的业务逻辑代码。再加上行为对象与功能逻辑的分离，贫血模型的开发方式，让行为对象的不断交叉使用，也是让系统不断增加复杂度，并到难以维护的根因。所以这一阶段要设计每一个可以表达领域概念的模型，并运用实体、聚合、领域服务来承载。

## 2. DDD 的概念

什么是充血模型？领域内都包括什么？实体、聚合、值对象，有什么区别？这样一些"为什么"的概念，也是战术设计过程中非常重要的知识项。搞清楚它们才能做 DDD 设计。

### 2.1 充血模型

**充血模型**，指将对象的属性信息与行为逻辑聚合到一个类中，常用的手段如：在对象内提供属于当前对象的`信息校验`、`拼装缓存Key`、`不含服务接口调用的逻辑处理`等。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-01-01.png" width="750px">
</div>

- 这样的方式可以在使用一个对象时，就顺便拿到这个对象的提供的一系列方法信息，所有使用对象的逻辑方法，都不需要自己再次处理同类逻辑。
- 但不要只是把充血模型，仅限于一个类的设计和一个类内的方法设计。充血还可以是整个包结构，一个包下包括了用于实现此包 Service 服务所需的各类零部件（模型、仓储、工厂），也可以被看做充血模型。
- 同时我们还会再一个同类的类下，提供对应的内部类，如用户实名，包括了，通信类、实名卡、银行卡、四要素等。它们都被写进到一个用户类下的内部子类，这样在代码编写中也会清晰的看到子类的所属信息，更容易理解代码逻辑，也便于维护迭代。

### 2.2 领域模型

**领域模型**，指特定业务领域内，业务规则、策略以及业务流程的抽象和封装。在设计手段上，通过风暴模型拆分领域模块，形成界限上下文。最大的区别在于把原有的`众多 Service + 数据模型`的方式，拆分为独立的有边界的领域模块。每个领域内创建自身所属的；领域对象（实体、聚合、值对象）、仓储服务(DAO 操作)、工厂、端口适配器Port（调用外部接口的手段）等。

那么，现在这里有几个概念：领域服务、领域对象、仓储定义、事件消息、端口适配器。我们先来看他们是怎么从贫血模型演变过来的，在细分讲解每个概念。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-01-02.png" width="750px">
</div>

- 在原本的 Service + 贫血的数据模型开发指导下，Service 串联调用每一个功能模块。这些基础设施（对象、方法、接口）是被相互调用的。这也是因为贫血模型并没有面向对象的设计，所有的需求开发只有详细设计。
- 换到充血模型下，现在我们以一个领域功能为聚合，拆分一个领域内所需的 Service 为领域服务，VO、Req、Res 重新设计为领域对象，DAO、Redis 等持久化操作为仓储等。举例：一套账户服务中的，授信认证、开户、提额降额等，每一个都是一个独立的领域，在每个独立的领域内，创建自身领域所需的各项信息。
- 领域模型还有一个特点，它自身只关注业务功能实现，不与外部任何接口和服务直连。如；不会直接调用 DAO 操作库，也不会调用缓存操作 Redis，更不会直接引入 RPC 连接其他微服务。而是通过仓库和端口适配器，定义调用外部数据的含有出入参对象的接口标准，让基础设施层做具体的调用实现——通过这样的方式让领域只关心业务实现，同时做好防腐。

### 2.3 实体、聚合、值对象

原本在贫血模型下的开发，常常是不会特别在意一个方法的出入参对象的，也经常是很多个服务共用一个VO对象作为入参，只要这个对象能把我需要的属性信息带进来就可以了。

但在 DDD 的领域模型设计下，领域对象的设计是非常面向对象的。而且在整个风暴事件的四色建模过程也是在以领域对象为驱动进行的。

实体、聚合、值对象，三者位于每个领域下的领域对象内，服务于领域内的领域服务。三个对象定义具体如下：

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-01-03.png" width="450px">
</div>

1. 胳膊、腿、身体，都是实体对象，和这个人生命有关。
2. 帽子、手套、裤衩，都是值对象，是这个人穿戴的，不具有生命属性。
3. 聚合，就是要写库一个事务，一次形成，可以聚合。把胳膊、腿、身体，放一块，一起让数据库执行事务。

> **实体**

是依托于持久化层数据以领域服务功能目标为指导设计的领域对象。持久化PO对象是原子类对象，不具有业务语义，而实体对象是具有业务语义且有唯一标识的对象，跟随于领域服务方法的全生命周期对象。如：用户PO持久化对象，会涵盖，用户的开户实体、授信实体、额度实体对象。也包括如商品下单时候的购物车实体对象。这个对象也通常是领域服务方法的入参对象。

- 概念：实体 = 唯一标识 + 状态属性 + 行为动作（功能），是DDD中的一个基本构建块，它代表了具有唯一标识的领域对象。实体不仅仅包含数据（状态属性），还包含了相关的行为（功能），并且它的标识在整个生命周期中保持不变。
- 特征：
  - **唯一标识**：实体具有一个可以区分其他实体的标识符。这个标识符可以是一个ID、一个复合键或者是一个自然键，关键是它能够唯一地标识实体实例。
  - **领域标识**：实体的标识通常来源于业务领域，例如用户ID、订单ID等。这些标识符在业务上有特定的含义，并且在系统中是唯一的。
  - **委派标识**：在某些情况下，实体的标识可能是由ORM（对象关系映射）框架自动生成的，如数据库中的自增主键。这种标识符虽然可以唯一标识实体，但它并不直接来源于业务领域。
- 用途：
  - **表达业务概念**：实体用于在软件中表达具体的业务概念，如用户、订单、交易等。通过实体的属性和行为，可以描述这些业务对象的特征和能力。
  - **封装业务逻辑**：实体不仅仅承载数据，还封装了业务规则和逻辑。这些逻辑包括验证数据的有效性、执行业务规则、计算属性值等。这样做的目的是保证业务逻辑的集中和一致性。
  - **保持数据一致性**：实体负责维护自身的状态和数据一致性。它确保自己的属性和关联关系在任何时候都是正确和完整的，从而避免数据的不一致性。
- 实现手段：
  - **定义实体类**：在代码中定义一个类，该类包含实体的属性、构造函数、方法等。
  - **实现唯一标识**：为实体类提供一个唯一标识的属性，如ID，并确保在实体的生命周期中这个标识保持不变。
  - **封装行为**：在实体类中实现业务逻辑的方法，这些方法可以操作实体的状态，并执行相关的业务规则。
  - **使用ORM框架**：利用ORM框架将实体映射到数据库表中，这样可以简化数据持久化的操作。
  - **实现领域服务**：对于跨实体或跨聚合的操作，可以实现领域服务来处理这些操作，而不是在实体中直接实现。
  - **使用领域事件**：当实体的状态发生变化时，可以发布领域事件，这样可以通知其他部分的系统进行相应的处理。

> **值对象**

这个对象在领域服务方法的生命周期过程内是不可变对象，也没有唯一标识。它通常是配合实体对象使用。如为实体对象提供对象属性值的描述，比如：一个公司雇员的级别值对象，一个下单的商品收货的四级地址信息对象。所以在开发值对象的时候，通常不会提供 setter 方法，而是提供构造函数或者 Builder 方法来实例化对象。这个对象通常不会独立作为方法的入参对象，但做可以独立作为出参对象使用。

- 概念：值对象是由一组属性组成的，它们共同描述了一个领域概念。与实体（Entity）不同，值对象不需要有一个唯一的标识符来区分它们。值对象通常是不可变的，这意味着一旦创建，它们的状态就不应该改变。
- 特征：
  - **不可变性（Immutability）**：值对象一旦被创建，它的状态就不应该发生变化。这有助于保证领域模型的一致性和线程安全性。
  - **等价性（Equality）**：值对象的等价性不是基于身份或引用，而是基于对象的属性值。如果两个值对象的所有属性值都相等，那么这两个对象就被认为是等价的。
  - **替换性（Replaceability）**：由于值对象是不可变的，任何需要改变值对象的操作都会导致创建一个新的值对象实例，而不是修改现有的实例。
  - **侧重于描述事物的状态**：值对象通常用来描述事物的状态，而不是事物的唯一身份。
  - **可复用性（Reusability）**：值对象可以在不同的领域实体或其他值对象中重复使用。
- 用途：
  - 金额和货币（如价格、工资、费用等）
  - 度量和数据（如重量、长度、体积等）
  - 范围或区间（如日期范围、温度区间等）
  - 复杂的数学模型（如坐标、向量等）
  - 任何其他需要封装的属性集合
- 实现手段：
  - **定义不可变类**：确保类的所有属性都是私有的，并且只能通过构造函数来设置。
  - **重写equals和hashCode方法**：这样可以确保值对象的等价性是基于它们的属性值，而不是对象的引用。
  - **提供只读访问器**：只提供获取属性值的方法，不提供修改属性值的方法。
  - **使用工厂方法或构造函数创建实例**：这有助于确保值对象的有效性和一致性。
  - **考虑序列化支持**：如果值对象需要在网络上传输或存储到数据库中，需要提供序列化和反序列化的支持。

> **聚合**

当你对数据库的操作需要使用到多个实体时，可以创建聚合对象。一个聚合对象，代表着一个数据库事务，具有事务一致性。聚合中的实体可以由聚合提供创建操作，实体也被称为聚合根对象。一个订单的聚合，会涵盖：下单用户实体对象、订单实体、订单明细实体和订单收货四级地址值对象。而那个作为入参的购物车实体对象，已经被转换为实体对象了。—— 聚合内事务一致性，聚合外最终一致性。

- 概念：聚合是领域模型中的一个关键概念，它是一组具有内聚性的相关对象的集合，这些对象一起工作以执行某些业务规则或操作。聚合定义了一组对象的边界，这些对象可以被视为一个单一的单元进行处理。
- 特征：
  - **一致性边界**：聚合确保其内部对象的状态变化是一致的。当对聚合内的对象进行操作时，这些操作必须保持聚合内所有对象的一致性。
  - **根实体**：每个聚合都有一个根实体（Aggregate Root），它是聚合的入口点。根实体拥有一个全局唯一的标识符，其他对象通过根实体与聚合交互。
  - **事务边界**：聚合也定义了事务的边界。在聚合内部，所有的变更操作应该是原子的，即它们要么全部成功，要么全部失败，以此来保证数据的一致性。
- 用途：
  1. **封装业务逻辑**：聚合通过将相关的对象和操作封装在一起，提供了一个清晰的业务逻辑模型，有助于业务规则的实施和维护。
  2. **保证一致性**：聚合确保内部状态的一致性，通过定义清晰的边界和规则，聚合可以在内部强制执行业务规则，从而保证数据的一致性。
  3. **简化复杂性**：聚合通过组织相关的对象，简化了领域模型的复杂性。这有助于开发者更好地理解和扩展系统。
- 实现手段：
  - **定义聚合根**：选择合适的聚合根是实现聚合的第一步。聚合根应该是能够代表整个聚合的实体，并且拥有唯一标识。
  - **限制访问路径**：只能通过聚合根来修改聚合内的对象，不允许直接修改聚合内部对象的状态，以此来维护边界和一致性。
  - **设计事务策略**：在聚合内部实现事务一致性，确保操作要么全部完成，要么全部回滚。对于聚合之间的交互，可以采用领域事件或其他机制来实现最终一致性。
  - **封装业务规则**：在聚合内部实现业务规则和逻辑，确保所有的业务操作都遵循这些规则。
  - **持久化**：聚合根通常与数据持久化层交互，以保存聚合的状态。这通常涉及到对象-关系映射（ORM）或其他数据映射技术。


### 2.4 仓储和适配器

在 DDD 的设计方法中，领域层做到了只关心领域服务实现。最能体现这样设计的就是仓库和适配器的设计。通常在 `Service + 数据模型`的设计中，会在 Service 中引入 Redis、RPC、配置中心等各类其他外部服务。但在 DDD 中，通过仓储和适配器以及基础设施层的定义，解耦了这部分内容。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-01-04.png" width="350px">
</div>

- 特征：
  - 封装持久化操作：Repository负责封装所有与数据源交互的操作，如创建、读取、更新和删除（CRUD）操作。这样，领域层的代码就可以避免直接处理数据库或其他存储机制的复杂性。
  - 领域对象的集合管理：Repository通常被视为领域对象的集合，提供了查询和过滤这些对象的方法，使得领域对象的获取和管理更加方便。
  - 抽象接口：Repository定义了一个与持久化机制无关的接口，这使得领域层的代码可以在不同的持久化机制之间切换，而不需要修改业务逻辑。

- 用途：
  - 数据访问抽象：Repository为领域层提供了一个清晰的数据访问接口，使得领域对象可以专注于业务逻辑的实现，而不是数据访问的细节。
  - 领域对象的查询和管理：Repository使得对领域对象的查询和管理变得更加方便和灵活，支持复杂的查询逻辑。
  - 领域逻辑与数据存储分离：通过Repository模式，领域逻辑与数据存储逻辑分离，提高了领域模型的纯粹性和可测试性。
  - 优化数据访问：Repository实现可以包含数据访问的优化策略，如缓存、批处理操作等，以提高应用程序的性能。

- 实现手段：
  - 定义Repository接口：在领域层定义一个或多个Repository接口，这些接口声明了所需的数据访问方法。
  - 实现Repository接口：在基础设施层或数据访问层实现这些接口，具体实现可能是使用ORM（对象关系映射）框架，如MyBatis、Hibernate等，或者直接使用数据库访问API，如JDBC等。
  - 依赖注入：在应用程序中使用依赖注入（DI）来将具体的Repository实现注入到需要它们的领域服务或应用服务中。这样做可以进一步解耦领域层和数据访问层，同时也便于单元测试。
  - 使用规范模式（Specification Pattern）：有时候，为了构建复杂的查询，可以结合使用规范模式，这是一种允许将业务规则封装为单独的业务逻辑单元的模式，这些单元可以被Repository用来构建查询。

>Repository模式是DDD（领域驱动设计）中的一个核心概念，它有助于保持领域模型的聚焦和清晰，同时提供了灵活、可测试和可维护的数据访问策略。

仓储解耦的手段使用了依赖倒置的设计，所有领域需要的外部服务，不在直接引入外部的服务，而是通过定义接口的方式，让基础设施层实现领域层接口（仓储/适配器）的方式来处理。

那么也就是基础设置层负责原则对接`数据库`、`缓存`、`配置中心`、`RPC接口`、`HTTP接口`、`MQ推送`等各项资源，并承接领域服务的接口调用各项服务为领域层提供数据能力。

同时这也会体现出，领域层的实现是具有业务语义的，而到了基础设置层则没有业务语义，都是原子的方法。通过原子方法的组合为领域业务语义提供支撑。

### 2.5 领域编排

在 DDD 中，每一个领域都是界限上下文拆分的独立结果，而实现业务流程的功能则需要串联各个领域模块提供一整条链路的完整服务。所以也常说领域内事务一致性，领域外最终一致性。

同时这些领域模块因为是独立的，所以也可以被复用。在不同的场景功能诉求下，可以选择不同的领域模块进行组装，这个过程就像搭积木一样。

但这里有一个取舍，如果项目相对来说并不大，也没有太多的编排处理。那么可以直接让触发器层对接领域层，减少编排层后，编码会更加便捷。

### 2.6 触发器

在所有的模型都定义完成后，领域业务被串联了。那么接下来则是使用，而使用的方式可以包括；接口（http/rpc）、消息监听、定时任务等方式，这些方式统一被定义为触发动作。

由触发发起对编排功能的调用处理，如：定时任务做信贷的计息、开户成功消息通知返利优惠券、提供接口让外部调用授信逻辑等——这些都是触发动作。

---

### Md Road Map Ddd Guide 02 (`docs/md/road-map/ddd-guide-02.md`)

---
title: DDD 建模方法
lock: need
---

# DDD 建模 —— 架构师总说的风暴模型是什么？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1356220874&bvid=BV1oz421q7x3&cid=1618776762&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

四色建模（风暴事件）是整个 DDD 这套软件设计方法中用于工程拆分界限上下文的非常重要的实践手段。通过建模过程快速识别业务领域中的关键事件和核心流程，也是在这个过程中设计出领域对象的，为后面详细设计和代码开发做指导。

你可以把整个过程理解为，为工程开发提供面向对象设计，涵盖；领域拆分、界限串联、功能聚合。所以相比`Service + 数据模型`的贫血开发方式，**DDD 前期需要付出更多的设计成本，但对于软件的长周期迭代，这样的好处是非常大的。**

## 1. 建模目的

工程的建模的目的是为了我们做工程开发时提供指导方案，就像一栋大楼的设计蓝图一样，也像一个超市中会有不同品类的货架，需要提前规划好。所以你需要在工程开发时所需的各类核心内容，都会在建模中体现，如：分几个包、有哪些核心对象、要串联什么流程、有哪些核心业务要实现、过程中与外部服务的交互。

为了达成讨论的共识，避免每个人都有不同的标准和词汇，我们通常会使用 DDD (领域驱动设计)提供的专门建模方法和统一的名词进行设计。DDD 的统一建模语言不涉及具体的技术编码，具有较强的通用性，因此可以让产品、研发、测试、架构师等人员一起参与讨论建模过程，促进跨职能的沟通和协作。如：领域、领域模型（实体、聚合、值对象）、领域服务、端口适配器、仓储、界限上下文、领域编排等名词。*这在上一节已经做了相关的解释。*

## 2. 如何建模

DDD 的建模过程，是以一个用户为起点，通过行为命令，发起行为动作，串联整个业务。而这个用户的起点最初来自于用例图的分析。用例图是用户与系统交互的最简表示形式，展现了用户和与他相关的用例之间的关系。通过用例图，我们可以分析出所有的行为动作。

在 DDD 中用于完成用户的行为命令和动作分析的过程，是一个四色建模的过程，也称作风暴模型。在使用 DDD 的标准对系统建模前，一定要先了解 DDD 的操作手段，这样才能让产品、研发、测试、运营等了解业务的伙伴，都能在同一个语言下完成系统建模。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-08.png" width="750px">
</div>

上图是整个四色建模的指导图，通过寻找领域事件，发起事件命令，完成领域事件的过程，完成 DDD 工程建模。

- 蓝色 - 决策命令，是用户发起的行为动作，如：开始签到、开始抽奖、查看额度等。
- 黄色 - 领域事件，过去时态描述。如：签到完成、抽奖完成、奖品发放完成。它所阐述的都是这个领域要完成的终态。
- 粉色 - 外部系统，如你的系统需要调用外部的接口完成流程。
- 红色 - 业务流程，用于串联决策命令到领域事件，所实现的业务流程。一些简单的场景则直接由决策命令到领域事件就可以了。
- 绿色 - 只读模型，做一些读取数据的动作，没有写库的操作。
- 棕色 - 领域对象，每个决策命令的发起，都是含有一个对应的领域对象。

**👩🏻‍🏫敲黑板** 综上，上图左下部分的示意图表达的是：“一个用户，通过一个策略命令，使用领域对象，通过业务流程，完成2个领域事件，调用1次外部接口”的过程。我们在整个 DDD 建模过程中，就是在寻找这些节点。

## 3. 超市举例

我们先通过一个真实场景的案例，代入下 DDD 四色建模的术语，这样可以更有益大家对四色建模理解。这个场景是一个在超市购物的场景。想象下，一个男人，得到了老婆的"命令"，去大超市拿着空的购物车，推进去一圈圈的走，最终完成购物打车回家。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-02-01.png" width="750px">
</div>

- 脑子中的想法，是媳妇给下达的指令。我们可以理解为决策命令。行为人带着决策命令来到超市。
- 购物车是一种实体，需要填充数据的实体。行为人，带着实体，进入到超市中从各个货架选购商品，装入购物车。选购商品为业务流程，装满的购物车为领域事件。也就是最终态，完成媳妇交代的任务。而手里的烟，则是另外一个领域事件。也就是说，一次的行为动作可以完成多个领域事件。
- 最终购物完成后，打车回家。则是下一个领域流程。通过把从加入出门、做地铁、进超市、采购、打车回家，一整条领域串联起来就是领域编排。

综上，DDD 的领域建模过程，就是一种真实的场景头脑风暴过程，所以可以让更多人同时讨论，拆分出各项领域的边界和领域模型。

## 4. 业务案例

接下来，我们在以一个真实的业务场景来分析系统的四色建模过程：

### 1. 产品诉求

如图，是一个复杂的营销抽奖场景玩法需求，涵盖了；`活动配置`、`签到&奖励`、`活动账户`、`抽奖策略「责任链+规则树」`、`库存扣减`、`抽奖满N次后阶梯抽奖`等。面对这样的复杂系统，非常适合使用 DDD 落地。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-02.png" width="550px">
</div>

分析需求；

1. 整体概率相加，总和为1或者分值计算，概率范围千分位
2. 抽奖为免费抽奖次数 + 用户消耗个人积分抽奖
3. 抽奖活动可给用户分配可抽奖次数，通过点击签到发放
4. 活动延伸配置用户库存消耗管理，单独提供表配置各类库存
   用户可用总库存、用户可用日库存
5. 部分抽奖规则，需要抽奖n次后解锁，才能有机会抽取
6. 抽奖完成增加（运气值/积分值/抽奖次数）记录，让用户获得奖品。
7. 奖品对接，自身的积分、内部系统的奖品
8. 随机积分，发给你积分。
9. 黑名单用户抽奖，则给予固定的奖品。

### 2. 用例图

根据业务需求画系统用例图；

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-07.png" width="650px">
</div>

- 用例图（英语：use case diagram）是用户与系统交互的最简表示形式，展现了用户和与他相关的用例之间的关系。通过用例图，人们可以获知系统不同种类的用户和用例。用例图也经常和其他图表配合使用。
- 用例图，也可以等同于是用户故事（英语：User story）（软件开发和项目管理中的常用术语），主旨是以日常语言或商务用语撰写句子，是一段简单的功能表述。以客户或使用者的观点撰写下有价值的功能、引导、框架来与使用者进行互动，进而推动工作进程。可以被认为是一种规格文件，但更精确而言，它代表客户的需求与方向。以该用户故事来反应对象在组织内的其工作职责、范围、需要进行的任务等。用户故事在敏捷开发方法中用来定义系统需要提供的功能和实现需求管理。
- 尽管用例本身会涉及大量细节和各种可能性，用例图却能提纲挈领地让人了解系统概况。它为“系统做什么”提供了简化了的图形表示，因此被誉为“搭建系统的蓝图”。

### 3. 寻找领域事件

接下来，大量的时间，都是在挖掘领域事件。这个过程就是一堆人头脑风暴的过程，避免错失流程节点。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-09.png" width="950px">
</div>

- 根据产品 PRD 文档，一起开会梳理有哪些领域事件。其实大多数领域事件一个人都可以想到，只是有些部分小的场景和将来可能产生的事件不一定覆盖全。所以要通过产品、测试、以及团队的架构师，一起讨论。
- 像是整个大营销的抽奖会包括如图所列举的事件。在列举这个阶段，你用在乎格式。也可以是每个人准备好黄色便签纸，想到一个就贴到黑板上一个，只是穷举完成。—— 实际做DDD中，也是这样用便签纸贴黑板，所以用不同的颜色做区分。

### 4. 识别领域角色和对象

在确定了领域事件以后，接下来要做的就是通过决策命令串联领域事件，并填充上所需要的领域对象。这块的操作，新手可以分开处理，如先给领域事件添加决策命令、执行用户和领域对象，最后再串联流程。就像 `事件风暴定义` 中的示意一样。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-10.png" width="950px">
</div>

- 首先，通过用户的行为动作，也就是决策命令，串联到对应的领域事件上。并对复杂的流程提供出红色的业务流程。
- 之后，为决策命令添加领域对象，每一个领域在整个流程中都起到了至关重要的作用。

### 5. 划分领域边界

有了识别出来的领域角色的流程，就可以非常容易的划分出领域边界了。先在事件风暴图上圈出领域边界，之后在单独提供领域划分。

#### 5.1 圈出领域

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-11.png" width="950px">
</div>

#### 5.2 领域边界

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/roadmap-ddd-stc-12.png" width="500px">
</div>

- 到这步咱们就可以获得整个项目中 DDD 的领域边界划分了。之后再往下就是具体的每个领域对象的详细设计和流程设计。

---

### Md Road Map Ddd Guide 03 (`docs/md/road-map/ddd-guide-03.md`)

---
title: DDD 工程模型
lock: need
---

# DDD 工程模型 - 在分布式微服务架构下，MVC比DDD，要乱的多！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1106396955&bvid=BV1Hw4m1k76m&cid=1626093529&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

凡是做到架构师岗位的，都是具有一定技术思维敏感性的，不会主观评价好和坏，但能推演出业务与技术的迭代发展被动熵增与减熵增的意识。就像拿MVC与DDD对比，也能确切的感受到，在架构方面对比于单体应用的分布式架构，是要额外引入非常多的技术栈使用。但这些模块在 MVC 下并没有设计好如何"安置"他们，就像一个老城区里突然引入了很多外来人口，不知道怎么安置一样。**不过 DDD 就像雄安新区做了整体规划！**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-00.gif" width="150px">
</div>

**什么是系统的工程结构，工程框架的作用是什么？**

其实，工程结构的存在作用目的，是为了承载工程系统开发的模型划分，定义工程服务开发过程中实施标准。说白了，就是你在工程实现时，在哪个层访问数据库、哪个层使用缓存、哪个层调用外部接口、哪个层做功能实现，这就是工程框架结构定义的目的。

但在 `Service + 贫血模型` 的三层结构开发指导下，是没有细分出面向对象工程结构设计的趋于划分的。所以在通常意义的 MVC 下，开发过程所有需要的内容，都会堆砌到 Service 实现类中。这也是为什么 DDD 领域驱动设计的落地工程结构，会出现；洋葱架构、整洁架构、菱形架构、六边形架构等这些架构模型。因为我们需要更细致的划分，来承载 DDD 设计概念中映射的领域、仓储、适配、编排、触发，并重视面向对象过程。—— 其实你一上学，学Java就开始学面向对象了，只不过一点点在忘记它。

>本节是DDD概率系列的第3节，讲解 DDD 架构设计，在 [bugstack.cn](https://bugstack.cn) 路书中有完整系列内容，可以查阅。

## 一、为啥需要架构

说到开发代码为啥需要架构，就想买了个房子，为啥要隔出厨房、客厅、卧室、卫生间一样，核心目的就是让不同的职责分配到不同的区域内。虽然在代码中是没有马桶要放卫生间、沙发要放客厅、床要放卧室。但他有一些列的科目信息要引入到工程。

**在工程开发时会涉及到的核心科目；**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-01.png" width="550px">
</div>

如；统一的异常、数据库的连接、日志的打印、外部服务的调用、消息的监听、任务的轮训以及服务的实现等一些列的东西要处理，分配到不同的工程包下承载。在 DDD 之前，我们一直用 MVC 的分层结构承接这些内容；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-02.png" width="550px">
</div>

通用的、配置的、组件的、持久化的、内部的、外部的，在以往的单体应用时代开发下，其实是没有这么多东西的，那时候的工程结构都偏向于 Service + 贫血模型实现。

但随着微服务的演进，越来越多的内容被填充到工程中，这个时候你细心的查看架构，就会发现原本的 MVC 结构其实已经变的非常混乱了。一个 Service 中为了实现自己的功能，要引入一堆的东西，这些原子的功能与 Service 自身的服务耦合在一块。也导致了工程的维护成本越来越大。 

>这样的三层工程结构分配方式，对于要承载庞大的分布式技术栈体系显然是有点小马拉大车，三缸机带不动SUV一样。

## 二、工程结构设计

2004年，Eric Evans 在发表了一部名为《Domain Driven Design》的著作。2005年 Alistair Cockburn 提出的“六边形关系图”理论，2008年 Jeffrey Palermo 提出了洋葱架构。虽然这些架构并不是专门为 DDD 而出，但巧的是这些架构都在 DDD 一书发表之后陆续推出新的架构模型。同时这些架构的分层设计方式也都与 DDD 非常契合，在这些架构下也可以很好的落地 DDD 设计方法。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-03.png" width="750px">
</div>
无论是六边形架构，还是洋葱架构，或是 张毅老师 - http://zhangyi.xyz/ 提到的南向网关/北向网关的菱形架构，他们的目标都是以领域服务为核心，隔离内部实现与外部资源的耦合。

在 DDD 分层架构下，以支撑 domain 核心领域实现拆分出基础设施（infrastructure），来承接对外部资源的调用。触发器（trigger）向外部提供服务。之后 app 为应用启动、api 为接口定义、types 为通用信息、case 为编排。

在这样一套结构下，用于开发工程的各项科目也可以被优雅的分配到各个分层结构了。相对于 Service + 数据模型的贫血模型结构，现在就主要以 domain 为核心开发业务功能，不会在 domain 工程模块下，引入其他各类外部组件了，这样就可以更加关心业务功能开发。

之后是这样的思想映射到工程中，常见的分层结构会有两套，一套是整洁分层，另外一套是六边形分层。

### 1. 整洁架构 - 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-04.png" width="750px">
</div>

- 整洁架构的分包形式，会将所有的外部依赖使用和工程内要对外的，统一定义到适配器层。这里可以理解为对外适配和对内适配。
- 阿里的 cola 偏整洁架构 [阿里架构 cola 的相关内容](https://www.aliyun.com/sswb/610119.html)

### 2. 六边形架构 - 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-05.png" width="750px">
</div>

六边形架构，会把本身提供到外部的放到trigger，让接口调用、消息监听、任务调度，都可以统一一个入口处理。而对于需要调用外部同类的能力统一放到 infrastructure 基础设施层，包括；数据库、缓存、配置、调用其他方的接口。

## 三、领域模型设计

虽然大家用的都是 DDD，也都有对应的模块和分包，但在细节之处还是会有一些差异。就像家里的家庭成员，衣服、裤子、鞋子，是所有人的衣服都放一起，还是每个人有独立的衣柜只放自己的。这块是有差异的。另外这东西没有绝对的好和坏，就像厨房里的碗筷是是放一起的，卫生间的马桶也是共用的，这说明分包也是需要按照最符合自己所需来设定。

### 1. 分包方式

如下，是两种分包方式；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/ddd-easy-guide-03-06.png" width="750px">
</div>

- 方式1；DDD 领域科目类型分包，类型之下写每个业务逻辑。
- 方式2；业务领域分包，每个业务领域之下有自己所需的 DDD 领域科目。

比如，你现在一个工程下有用户、积分、抽奖、支付，（紧凑的聚合类微服务有时候更易于维护），那么这些包一种是分为独立的业务包方式2这种，另外一种就是大家都在一个坛子里吃饭，要啥去各个地方找。所以你更倾向于那种呢？

### 2. 领域模型

DDD 领域驱动设计的中心，主要在于领域模型的设计，以领域所需驱动功能实现和数据建模。一个领域服务下面会有多个领域模型，每个领域模型都是一个充血结构。**一个领域模型 = 一个充血结构**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ddd-01.png" width="750px">
</div>

- model 模型对象；
  - aggreate：聚合对象，实体对象、值对象的协同组织，就是聚合对象。
  - entity：实体对象，大多数情况下，实体对象(Entity)与数据库持久化对象(PO)是1v1的关系，但也有为了封装一些属性信息，会出现1vn的关系。
  - valobj：值对象，通过对象属性值来识别的对象 By 《实现领域驱动设计》
- repository 仓储服务；从数据库等数据源中获取数据，传递的对象可以是聚合对象、实体对象，返回的结果可以是；实体对象、值对象。因为仓储服务是由基础层(infrastructure) 引用领域层(domain)，是一种依赖倒置的结构，但它可以天然的隔离PO数据库持久化对象被引用。
- service 服务设计；这里要注意，不要以为定义了聚合对象，就把超越1个对象以外的逻辑，都封装到聚合中，这会让你的代码后期越来越难维护。聚合更应该注重的是和本对象相关的单一简单封装场景，而把一些重核心业务方到 service 里实现。**此外；如果你的设计模式应用不佳，那么无论是领域驱动设计、测试驱动设计还是换了三层和四层架构，你的工程质量依然会非常差。**
- 对象解释
  - DTO 数据传输对象 (data transfer object)，DAO与业务对象或数据访问对象的区别是：DTO的数据的变异子与访问子（mutator和accessor）、语法分析（parser）、序列化（serializer）时不会有任何存储、获取、序列化和反序列化的异常。即DTO是简单对象，不含任何业务逻辑，但可包含序列化和反序列化以用于传输数据。

## 四、分层调用链路

接下来我们把 DDD 的分层架构平铺展开，看看从一个接口的实现到各个模块分层中的调用链路关系是什么样的。这样在做自己的代码开发中也可以参考到应该把什么的功能分配到哪个模块中处理。



从APP层、触发器层、应用层，这三块主要对领域层的上下文逻辑封装、触发式(MQ、HTTP、JOB)使用，并最终在应用层中打包发布上线。这一部分的都是使用的处理，所以也不会有太复杂的操作。

当进入领域层开始，也是智力集中体现的开始了。所有你对工程的抽象能力，都在这一块区域体现。

**关于对象定义**；vo、po、dto、entity、aggregate、req、res、response

以下描述使用场景为，在 DDD 领域驱动架构下（六边形、整洁、COLA）

domain 领域层；
- entity，实体对象，如雇员用户的基本信息、订单信息、配送信息
- vo（value object），值对象，用于描述实体对象信息。如一个人，这个雇员用户的基本 level 枚举值对象、这个人居住地址四级信息对象。这些对象不具有唯一性，也就是不具有生命特征。就像你，之后你的衣服，你的胡子。
- aggregate，聚合对象，当我们要写一笔订单入口的时候，需要做事务，事务如果需要一组对象；订单记录、账户记录、库存记录等，这些实体对象+值对象，写入到聚合对象内，一起提交过去。

* 以前的 MVC 下的 XXXVo、XxxReq、XxxRes，现在被领域细分成各个模块下的，实体、聚合、值对象了。*

infrastructure 基础设施层；
- po 数据库持久化对象，用于映射数据库表字段的。这个对象不要做业务流程，只提供数据库数据
- dto 数据传输对象，这个对象也会在基础设施层出现，用于与外部的接口对接。比如 rpc 接口、http 接口，出入参的对象，都叫做数据传输对象。命名为 XxxRequestDTO、XxxResponseDTO 支付包的sdk包里就是这样命名的。

api 层：
- dto 对象，接口的出入参，数据传输对象。命名为 XxxRequestDTO、XxxResponseDTO
- response<?> 对象，包装结果对象，提供 code、info、data，准确描述错误码以及data数据，data数据是泛型，用于包装 XxxResponseDTO 结果。当你f12浏览器，一些互联网的web服务，观察他的接口，就会看到这样的结构。

case 编排层：
- 这一层承接 web 的接口编排动作，串联 domain 领域流程。通常2个方案，一个是引入 api 层，定义的对象。另外一个就是多一层转换，在一层定义 api 层对应的 XxxRequestDTO -> XxxRequest、XxxResponseDTO -> XxxResponse

## 五、工程架构案例

### 1. 环境

- JDK 1.8
- Maven 3.8.6
- SpringBoot 2.7.2
- MySQL 5.7 - 如果你使用 8.0 记得更改 pom.xml 中的 mysql 引用
- Dubbo - [https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/](https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/) 文档&广播模式地址说明

### 2. 架构

- **源码**：[`https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd`](https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd)
- **树形**：`安装 brew install tree` `IntelliJ IDEA Terminal 使用 tree`

```
/* Detailed source-code truncated for AI context efficiency. */
```

以上是整个🏭工程架构的 tree 树形图。整个工程由  xfg-frame-app 模的 SpringBoot 驱动。这里小傅哥在 domain 领域模型下提供了 order、rule、user 三个领域模块。并在每个模块下提供了对应的测试内容。这块是整个模型的重点，其他模块都可以通过测试看到这里的调用过程。

### 3. 领域

一个领域模型中包含3个部分；model、repository、service 三部分；
- model 对象的定义 【含有；valobj = VO、entity、Aggregate】
- repository 仓储的定义【含有PO】
- service 服务实现

以上3个模块，一般也是大家在使用 DDD 时候最不容易理解的分层。比如 model 里还分为；valobj - 值对象、entity 实体对象、aggregates 聚合对象；
- **值对象**：表示没有唯一标识的业务实体，例如商品的名称、描述、价格等。
- **实体对象**：表示具有唯一标识的业务实体，例如订单、商品、用户等；
- **聚合对象**：是一组相关的实体对象的根，用于保证实体对象之间的一致性和完整性；

关于model中各个对象的拆分，尤其是聚合的定义，会牵引着整个模型的设计。当然你可以在初期使用 DDD 的时候不用过分在意领域模型的设计，可以把整个 domain 下的一个个包当做充血模型结构，这样编写出来的代码也是非常适合维护的。

### 4. 环境(开发/测试/上线)

**源码**：`xfg-frame-ddd/pom.xml`

```pom
<profile>
    <id>dev</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <profileActive>dev</profileActive>
    </properties>
</profile>
<profile>
    <id>test</id>
    <properties>
        <profileActive>test</profileActive>
    </properties>
</profile>
<profile>
    <id>prod</id>
    <properties>
        <profileActive>prod</profileActive>
    </properties>
</profile>
```

- 定义环境；开发、测试、上线。

**源码**：`xfg-frame-app/application.yml`

```java
spring:
  config:
    name: xfg-frame
  profiles:
    active: dev # dev、test、prod
```

- 除了 pom 的配置，还需要在 application.yml 中指定环境。这样就可以对应的加载到；`application-dev.yml`、`application-prod.yml`、`application-test.yml` 这样就可以很方便的加载对应的配置信息了。尤其是各个场景中切换会更加方便。

### 5. 切面

一个工程开发中，有时候可能会有很多的统一切面和启动配置的处理，这些内容都可以在 xfg-frame-app 完成。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-04.png?raw=true" width="450px"/>
</div>

**源码**：`cn.bugstack.xfg.frame.aop.RateLimiterAop`

```java
@Slf4j
@Aspect
public class RateLimiterAop {

    private final long timeout;
    private final double permitsPerSecond;
    private final RateLimiter limiter;

    public RateLimiterAop(double permitsPerSecond, long timeout) {
        this.permitsPerSecond = permitsPerSecond;
        this.timeout = timeout;
        this.limiter = RateLimiter.create(permitsPerSecond);
    }

    @Pointcut("execution(* cn.bugstack.xfg.frame.trigger..*.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()", argNames = "jp")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        boolean tryAcquire = limiter.tryAcquire(timeout, TimeUnit.MILLISECONDS);
        if (!tryAcquire) {
            Method method = getMethod(jp);
            log.warn("方法 {}.{} 请求已被限流，超过限流配置[{}/秒]", method.getDeclaringClass().getCanonicalName(), method.getName(), permitsPerSecond);
            return Response.<Object>builder()
                    .code(Constants.ResponseCode.RATE_LIMITER.getCode())
                    .info(Constants.ResponseCode.RATE_LIMITER.getInfo())
                    .build();
        }
        return jp.proceed();
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}
```

**使用**

```java
# 限流配置
rate-limiter:
  permits-per-second: 1
  timeout: 5
```

- 这样你所有的通用配置，又和业务没有太大的关系的，就可以直接写到这里了。—— 具体可以参考代码。

## 六、工程测试验证

- 首先；整个工程由 SpringBoot 驱动，提供了 road-map.sql 测试 SQL 库表语句。你可以在自己的本地mysql上进行执行。它会创建库表。
- 之后；在 application.yml 配置数据库链接信息。
- 之后就可以打开 ApiTest 进行测试了。你可以点击 Application 类的绿色箭头启动工程，使用触发器里的接口调用测试，或者单元测试RPC接口，小傅哥也提供了泛化调用的方式。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-05.png?raw=true" width="950px"/>
</div>

- 如果你正常获取了这样的结果信息，那么说明你已经启动成功。接下来就可以对照着DDD的结构进行学习，以及使用这样的工程结构开发自己的项目。

---

### Md Road Map Ddd Model (`docs/md/road-map/ddd-model.md`)

---
title: DDD 建模案例
lock: need
---

# 架构的本质之 DDD 四色建模

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1154849743&bvid=BV1yZ421s7En&cid=1550075616&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

- 项目地址：[https://t.zsxq.com/199mpn9Lt](https://t.zsxq.com/199mpn9Lt)

---

### Md Road Map Ddd (`docs/md/road-map/ddd.md`)

---
title: DDD 架构设计
lock: need
---

# 架构的本质之 DDD 架构

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=402885332&bvid=BV1kV411g7GX&cid=1182477982&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

从最早接触 DDD 架构，到后来用 DDD 架构不断的承接项目开发，一次次在项目开发中的经验积累。对 DDD 有了不少的理解。DDD 是一种思想，落地的形态和结构会有不同的方式，甚至在编码上也会有风格的差异。但终期目标就一个；”提供代码的可维护性，降低迭代开发成本。“也是康威定律所述：”任何组织在设计一套系统时，所交付的设计方案在结构上都与该组织的沟通结构保持一致。“

但 DDD 与 MVC 相比差异较大，贸然用理论驱动代码开发，会让整个工程变得非常混乱，甚至可能虽然是用的 DDD 但最后写出来了一片四不像的 MVC 代码。所以对于程序员👨🏻‍💻来说，先能上手一个工程，在从工程了解理论会更加容易。为此小傅哥想以此文，通过实战编码的方式向大家分享 DDD 架构，并能让大家上手的 DDD 架构。

## 一、问题碰撞

`你用 MVC 写代码，遇到过最大的问题是什么？`🤔

简单、容易、好理解，是 MVC 架构的特点，但也正因为简单的分层逻辑，在适配较复杂的场景并且需要长周期的维护时，代码的迭代成本就会越来越高。如图；

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-01.png?raw=true" width="650px"/>
</div>

-  如果你接触过较大型且已经长期维护项目的 MVC 架构，你就会发现这里的 DAO、PO（持久化）、VO（业务对象） 对象，在 Service 层相互调用。那么长期开发后，就导致了各个 VO 里的属性字段数量都被撑的特别大。这样的开发方式，将`”状态”`、`“行为“`分离到不同的对象中，代码的意图渐渐模糊，膨胀、臃肿和不稳定的架构，让迭代成本增加。
-  而 DDD 架构首先以解决此类问题为主，将各个属于自己领域范围内的行为和逻辑封装到自己的领域包下处理。这也是 DDD 架构设计的精髓之一。它希望在分治层面合理切割问题空间为更小规模的若干子问题，而问题越小就容易被理解和处理，做到高内聚低耦合。这也是康威定律所提到的，解决复杂场景的设计主要分为：分治、抽象和知识。

## 二、简化理解

在给大家讲解 MVC 架构的时候，小傅哥提到了一个简单的开发模型。开发代码可以理解为：`“定义属性 -> 创建方法 -> 调用展示” `但这个模型结构过于简单，不太适合运用了各类分布式技术栈以及更多逻辑的 DDD 架构。所以在 DDD 这里，我们把开发代码可以抽象为：`“触发 -> 函数 -> 连接”` 如图；

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-02.png?raw=true" width="550px"/>
</div>

- DDD 架构常用于微服务场景，因此也一个系统的调用方式就不只是 HTTP 还包括；`RPC 远程`、`MQ 消息`、`TASK 任务`，因此这些种方式都可以理解为触发。
- 通过触发调用函数方法，我们这里可以把各个服务都当成一个函数方法来看。而函数方法通过连接，调用到其他的接口、数据库、缓存来完成函数逻辑。

接下来，小傅哥在带着大家把这些所需的模块，拆分到对应的DDD系统架构中。

## 三、架构分层

如下是 DDD 架构的一种分层结构，也可以有其他种方式，核心的重点在于适合你所在场景的业务开发。以下的分层结构，是小傅哥在使用 DDD 架构多种的方式开发代码后，做了简化和处理的。右侧的连线是各个模块的依赖关系。接下来小傅哥就给大家做一下模块的介绍。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-03.png?raw=true" width="850px"/>
</div>

- **接口定义 - xfg-frame-api**：因为微服务中引用的 RPC 需要对外提供接口的描述信息，也就是调用方在使用的时候，需要引入 Jar 包，让调用方好能依赖接口的定义做代理。
- **应用封装 - xfg-frame-app**：这是应用启动和配置的一层，如一些 aop 切面或者 config 配置，以及打包镜像都是在这一层处理。你可以把它理解为专门为了启动服务而存在的。
- **领域封装 - xfg-frame-domain**：领域模型服务，是一个非常重要的模块。无论怎么做DDD的分层架构，domain 都是肯定存在的。在一层中会有一个个细分的领域服务，在每个服务包中会有【模型、仓库、服务】这样3部分。
- **仓储服务 - xfg-frame-infrastructure**：基础层依赖于 domain 领域层，因为在 domain 层定义了仓储接口需要在基础层实现。这是依赖倒置的一种设计方式。
- **领域封装 - xfg-frame-trigger**：触发器层，一般也被叫做 adapter 适配器层。用于提供接口实现、消息接收、任务执行等。所以对于这样的操作，小傅哥把它叫做触发器层。
- **类型定义 - xfg-frame-types**：通用类型定义层，在我们的系统开发中，会有很多类型的定义，包括；基本的 Response、Constants 和枚举。它会被其他的层进行引用使用。
- **领域编排【可选】 - xfg-frame-case**：领域编排层，一般对于较大且复杂的的项目，为了更好的防腐和提供通用的服务，一般会添加 case/application 层，用于对 domain 领域的逻辑进行封装组合处理。

## 四、领域分层

DDD 领域驱动设计的中心，主要在于领域模型的设计，以领域所需驱动功能实现和数据建模。一个领域服务下面会有多个领域模型，每个领域模型都是一个充血结构。**一个领域模型 = 一个充血结构**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ddd-01.png?raw=true" width="950px"/>
</div>

- model 模型对象；

  - aggreate：聚合对象，实体对象、值对象的协同组织，就是聚合对象。
  - entity：实体对象，大多数情况下，实体对象(Entity)与数据库持久化对象(PO)是1v1的关系，但也有为了封装一些属性信息，会出现1vn的关系。
  - valobj：值对象，通过对象属性值来识别的对象 By 《实现领域驱动设计》 
- repository 仓储服务；从数据库等数据源中获取数据，传递的对象可以是聚合对象、实体对象，返回的结果可以是；实体对象、值对象。因为仓储服务是由基础层(infrastructure) 引用领域层(domain)，是一种依赖倒置的结构，但它可以天然的隔离PO数据库持久化对象被引用。
- service 服务设计；这里要注意，不要以为定义了聚合对象，就把超越1个对象以外的逻辑，都封装到聚合中，这会让你的代码后期越来越难维护。聚合更应该注重的是和本对象相关的单一简单封装场景，而把一些重核心业务方到 service 里实现。**此外；如果你的设计模式应用不佳，那么无论是领域驱动设计、测试驱动设计还是换了三层和四层架构，你的工程质量依然会非常差。**

- 对象解释
   - DTO 数据传输对象 (data transfer object)，DAO与业务对象或数据访问对象的区别是：DTO的数据的变异子与访问子（mutator和accessor）、语法分析（parser）、序列化（serializer）时不会有任何存储、获取、序列化和反序列化的异常。即DTO是简单对象，不含任何业务逻辑，但可包含序列化和反序列化以用于传输数据。 

## 五、架构源码

### 1. 环境

- JDK 1.8
- Maven 3.8.6
- SpringBoot 2.7.2
- MySQL 5.7 - 如果你使用 8.0 记得更改 pom.xml 中的 mysql 引用
- Dubbo - [https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/](https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/multicast/) 文档&广播模式地址说明

### 2. 架构

- **源码**：[`https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd`](https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd)
- **树形**：`安装 brew install tree` `IntelliJ IDEA Terminal 使用 tree`

```
/* Detailed source-code truncated for AI context efficiency. */
```

以上是整个🏭工程架构的 tree 树形图。整个工程由  xfg-frame-app 模的 SpringBoot 驱动。这里小傅哥在 domain 领域模型下提供了 order、rule、user 三个领域模块。并在每个模块下提供了对应的测试内容。这块是整个模型的重点，其他模块都可以通过测试看到这里的调用过程。

### 3. 领域

一个领域模型中包含3个部分；model、repository、service 三部分；
- model 对象的定义 【含有；valobj = VO、entity、Aggregate】
- repository 仓储的定义【含有PO】
- service 服务实现

以上3个模块，一般也是大家在使用 DDD 时候最不容易理解的分层。比如 model 里还分为；valobj - 值对象、entity 实体对象、aggregates 聚合对象；
- **值对象**：表示没有唯一标识的业务实体，例如商品的名称、描述、价格等。
- **实体对象**：表示具有唯一标识的业务实体，例如订单、商品、用户等；
- **聚合对象**：是一组相关的实体对象的根，用于保证实体对象之间的一致性和完整性；

关于model中各个对象的拆分，尤其是聚合的定义，会牵引着整个模型的设计。当然你可以在初期使用 DDD 的时候不用过分在意领域模型的设计，可以把整个 domain 下的一个个包当做充血模型结构，这样编写出来的代码也是非常适合维护的。

### 4. 环境(开发/测试/上线)

**源码**：`xfg-frame-ddd/pom.xml`

```pom
<profile>
    <id>dev</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <profileActive>dev</profileActive>
    </properties>
</profile>
<profile>
    <id>test</id>
    <properties>
        <profileActive>test</profileActive>
    </properties>
</profile>
<profile>
    <id>prod</id>
    <properties>
        <profileActive>prod</profileActive>
    </properties>
</profile>
```

- 定义环境；开发、测试、上线。

**源码**：`xfg-frame-app/application.yml`

```java
spring:
  config:
    name: xfg-frame
  profiles:
    active: dev # dev、test、prod
```

- 除了 pom 的配置，还需要在 application.yml 中指定环境。这样就可以对应的加载到；`application-dev.yml`、`application-prod.yml`、`application-test.yml` 这样就可以很方便的加载对应的配置信息了。尤其是各个场景中切换会更加方便。

### 5. 切面

一个工程开发中，有时候可能会有很多的统一切面和启动配置的处理，这些内容都可以在 xfg-frame-app 完成。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-04.png?raw=true" width="450px"/>
</div>

**源码**：`cn.bugstack.xfg.frame.aop.RateLimiterAop`

```java
@Slf4j
@Aspect
public class RateLimiterAop {

    private final long timeout;
    private final double permitsPerSecond;
    private final RateLimiter limiter;

    public RateLimiterAop(double permitsPerSecond, long timeout) {
        this.permitsPerSecond = permitsPerSecond;
        this.timeout = timeout;
        this.limiter = RateLimiter.create(permitsPerSecond);
    }

    @Pointcut("execution(* cn.bugstack.xfg.frame.trigger..*.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()", argNames = "jp")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        boolean tryAcquire = limiter.tryAcquire(timeout, TimeUnit.MILLISECONDS);
        if (!tryAcquire) {
            Method method = getMethod(jp);
            log.warn("方法 {}.{} 请求已被限流，超过限流配置[{}/秒]", method.getDeclaringClass().getCanonicalName(), method.getName(), permitsPerSecond);
            return Response.<Object>builder()
                    .code(Constants.ResponseCode.RATE_LIMITER.getCode())
                    .info(Constants.ResponseCode.RATE_LIMITER.getInfo())
                    .build();
        }
        return jp.proceed();
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}
```

**使用**

```java
# 限流配置
rate-limiter:
  permits-per-second: 1
  timeout: 5
```

- 这样你所有的通用配置，又和业务没有太大的关系的，就可以直接写到这里了。—— 具体可以参考代码。

## 六、测试验证

- 首先；整个工程由 SpringBoot 驱动，提供了 road-map.sql 测试 SQL 库表语句。你可以在自己的本地mysql上进行执行。它会创建库表。
- 之后；在 application.yml 配置数据库链接信息。
- 之后就可以打开 ApiTest 进行测试了。你可以点击 Application 类的绿色箭头启动工程，使用触发器里的接口调用测试，或者单元测试RPC接口，小傅哥也提供了泛化调用的方式。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230624-05.png?raw=true" width="950px"/>
</div>

- 如果你正常获取了这样的结果信息，那么说明你已经启动成功。接下来就可以对照着DDD的结构进行学习，以及使用这样的工程结构开发自己的项目。

---

### Md Road Map Disruptor (`docs/md/road-map/disruptor.md`)

---
title: Disruptor
lock: need
---

# Disruptor 高性能环形消息队列应用，Log4j 2 也用到了这套技术。

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

说到底，无论是晋升述职还是面试考察，编程技能的展现总是在那些技术的横向对比和深度的了解运用。知其一，也知其二。一个场景的问题，往往也会对应着多种的解决方案，从没有绝对的好和不好，都是是否适合而已。所以，往往技术越好的，也越低调，不那么咋咋呼呼的。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-disruptor-01.gif" width="200px"/>
</div>

**什么是柔性事务？**

在分布式软件系统架构设计中，所有的并发资源的竞争，都会往`无锁化`、`非独占竞争`，以及`柔性事务`设计。柔性事务用于替代传统事务管理中（如ACID属性：原子性、一致性、隔离性、持久性），在分布式架构系统中的使用场景。通过消息、补偿，协调不同服务间的一致性。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-disruptor-02.png" width="550px"/>
</div>

那么在消息的使用中，除了有 MQ 消息，使用于微服务之间。还有本地消息，可以作用在各个领域间驱动流程。关于本地消息可以用，Spring 的监听、Redis 发布订阅、Guava EventBus 事件总线，这些内容在小傅哥博客 [bugstack.cn](https://bugstack.cn) 《路书》中有相关的案例。之后本节咱们介绍一个新的高性能组件 Disruptor 的使用。

## 一、关于 Disruptor

Disruptor 是一种高性能的并发框架，最初由 LMAX 开发，用于解决高吞吐量、低延迟的消息处理问题。它提供了一种无锁的、有序的事件处理模型，非常适合处理需要高性能的场景。Disruptor 本身并不是用于实现事务的框架，而是一个事件处理器。因此，要在 Disruptor 上实现柔性事务，需要结合其事件处理能力与柔性事务的模式。

- 源码：[https://github.com/LMAX-Exchange/disruptor](https://github.com/LMAX-Exchange/disruptor)
- 文档：[https://lmax-exchange.github.io/disruptor/](https://lmax-exchange.github.io/disruptor/) - 谷歌浏览器右键点翻译为中文。

## 二、实战案例

### 1. 工程结构

小傅哥准备好了一份基于 Disruptor 事件消息的使用案例工程，你可以直接上手体现。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-disruptor-03.png" width="400px"/>
</div>

- app 是使用的启动层、trigger 是提供接口、监听消息、处理任务的触发器层。
- 在这里我们通过 trigger 下的 event 包，监听事件消息。之后把这个 XxxEventHandler 让 app 层下的 Disruptor 进行实例化。

### 2. 引入POM

```pom

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.4</version>
</dependency>
```

- 引入 disruptor pom 包。

### 3. 监听消息

```java
@Slf4j
public class XxxEventHandler implements EventHandler<XxxEventHandler.Message> {

    @Override
    public void onEvent(Message longEvent, long l, boolean b) throws Exception {
        log.info("接收消息：{}", longEvent.getValue());
    }

    @Data
    public static class Message {
        private String value;
    }

}
```

- 在 trigger 下 event 包内，加一个实现了 disruptor EventHandler 的监听实现类，消息体类型我们定义到 XxxEventHandler 中，也就是 Message。具体生产使用的时候，按需调整。
- 这个接收消息的过程和使用 MQ 的方式是一样的。

### 4. 实例化监听

```java
@Configuration
public class DisruptorConfig {

    private final ExecutorService executor = Executors.newCachedThreadPool();

    @Bean("xxxEventDisruptor")
    public Disruptor<XxxEventHandler.Message> disruptor() {
        // 环形队列的大小，注意要是2的幂
        int bufferSize = 1024;

        // 创建Disruptor
        Disruptor<XxxEventHandler.Message> disruptor = new Disruptor<>(XxxEventHandler.Message::new, bufferSize, executor);

        // 连接事件处理器
        disruptor.handleEventsWith(new XxxEventHandler());

        // 开始Disruptor
        disruptor.start();

        return disruptor;
    }

}
```

- 在 App 模块下，有一个 config 专门的配置类，在这里配置下消息监听。这个过程和我们之前使用的 Redis 发布订阅是一样的。

### 5. 推送消息(Test)

```java
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class DisruptorTest {

    @Resource
    private Disruptor<XxxEventHandler.Message> xxxEventDisruptor;

    @Test
    public void test_publishEvent() throws InterruptedException {

        for (int i = 0; i < 10; i++) {
            xxxEventDisruptor.publishEvent((event, sequence) -> event.setValue("你好，我是 Disruptor Message"));
        }

        // 暂停 - 测试完手动关闭程序
        new CountDownLatch(1).await();
    }

}
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 提供一个单测来测试消息推送，这样你就可以监听到消息了。

## 三、总结

在美团、京东、阿里，等各个大厂中都有很多这样的组件使用，在美团发布过的文章中[《高性能队列——Disruptor》](https://tech.meituan.com/2016/11/18/disruptor.html) 还有一个对应的压测数据。CPU:Intel Core i7-2720QM，JVM:Java 1.6.0_25 64-bit，OS:Ubuntu 11.04

| -                  | ABQ       | Disruptor  |
| :----------------- | :-------- | :--------- |
| Unicast: 1P – 1C   | 4,057,453 | 22,381,378 |
| Pipeline: 1P – 3C  | 2,006,903 | 15,857,913 |
| Sequencer: 3P – 1C | 2,056,118 | 14,540,519 |
| Multicast: 1P – 3C | 260,733   | 10,860,121 |
| Diamond: 1P – 3C   | 2,082,725 | 15,295,197 |

- 依据并发竞争的激烈程度的不同，Disruptor比ArrayBlockingQueue吞吐量快4~7倍。

---

另外，Log4j 2 采用了 Disruptor（一种无锁的线程间通信库），提高吞吐量降低延迟。在生产使用中，大并发的系统注意 Log4j 版本。官网说明：[https://logging.apache.org/log4j/2.12.x/manual/async.html](https://logging.apache.org/log4j/2.12.x/manual/async.html)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-disruptor-04.png" width="850px"/>
</div>

- **异步 Logger**是 Log4j 2 中的新增功能。其目的是尽快从对 Logger.log 的调用返回到应用程序。您可以选择使所有 Logger 异步，或使用同步和异步 Logger 的混合。使所有 Logger 异步将提供最佳性能，而混合使用则可为您提供更大的灵活性。
- **LMAX Disruptor 技术**。异步记录器内部使用 [Disruptor（](https://logging.apache.org/log4j/2.12.x/manual/async.html#UnderTheHood)一种无锁的线程间通信库）而不是队列，从而实现更高的吞吐量和更低的延迟。
- 作为异步日志记录器工作的一部分，**异步附加器**已得到增强，可以在批处理结束时（当队列为空时）刷新到磁盘。这会产生与配置“immediateFlush=true”相同的结果，即所有收到的日志事件始终在磁盘上可用，但效率更高，因为它不需要在每个日志事件上都接触磁盘。（异步附加器在内部使用 ArrayBlockingQueue，不需要类路径上的 Disruptor jar。）

---

### Md Road Map Docker Deploy Project (`docs/md/road-map/docker-deploy-project.md`)

---
title: Docker 部署项目
lock: need
---

# Docker 部署项目

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115771615219475&bvid=BV1K6B3BuEwP&cid=34939144626&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

在实践中发现，不少伙伴不了解云服务器是什么，搞不清楚云服务器和本地电脑的关系，也不知道怎么把一个项目部署到云服务器。但作为程序员学习编程，又离不开云服务器，逃避不了一点！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-01.png" width="150px">
</div>

**看看是不你也遇到了这些问题**

云服务器选什么系统、云服务器怎么安装环境、Intellij IDEA 怎么连接云服务器、云服务器安装了 Docker 本地电脑还用安装吗、SpringBoot 项目怎么部署到云服务器、构建的镜像推送不到 Docker Hub 怎么办？

等等，一些列的问题，把小白拦截在云服务器的门外。不过，没关系，今天小傅哥就帮你把这接腿🦵🏻的事办啦，让你以后畅通无阻。

>文末提供了，5个AI项目、5个业务项目、8个组件项目、1套源码项目，还有非常多的学习资料，你可以全部获取学习，积累来自互联网大厂的经验。

## 零、所需资源

- [购买云服务器 2c4g](http://618.gaga.plus/)
- [工程案例代码 xfg-dev-tech-docker-deploy](https://github.com/fuzhengwei/xfg-dev-tech-docker-deploy)
- [云服务器安装脚本](https://gaga.plus/app/dev-ops/index.html)
- [云服务器连接工具](https://origin.bugstack.cn/md/road-map/tool.html)
- [阿里云docker镜像仓库](https://cr.console.aliyun.com/cn-hangzhou/instance/repositories)

## 一、云服务器是什么？

在使用云服务器之前，我们先来理解下云服务器是什么，把定位搞清楚，后面的事才好办。如图；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-01.png" width="650px">
</div>

- 云服务器，你可以理解为是你的书桌上摆着的2台电脑。你可以通过其中一台电脑，以 SSH 方式连接另外一台电脑，并在另外一台电脑安装 MySQL、Redis、Ollama 等，以减轻当前这台电脑的压力。让手里的这台电脑只负责代码开发，需要什么资源就连接另外一台电脑的上软件即可。
- 现在为了方便的让每个人都可以拥有自己的另外一台电脑，有一些公司就把电脑集中起来搭建成了服务器机房，在通过提供公网IP让你在购买云服务器后，可以用你的电脑连接上云服务器电脑，进行软件的部署和程序对软件的连接。

## 二、云服务器咋操作（命令）

当然，云服务器的操作也需要一点 Linux 命令的知识，它不是那种`点点点`的方式使用电脑，而是通过命令行。比如，`ls` 查看文件列表、`mkdir` 创建文件夹、`chmod +x` 给文件授予执行权限，当然也有些死鬼告诉你执行 `rm -rf /*` 今天一天都不用干活！

为了，让小伙伴们，先不需要看非常的多的资料，就能快速的使用起这些命令。这里小傅哥做了个模拟 Linux 服务器，进行命令练习的网页，你可以通过页面的模拟建立 SSH 连接，之后学习这些命令。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-02.png" width="750px">
</div>

地址：[https://gaga.plus/app/dev-ops/tutorials/what-is-a-cloud-server.html](https://gaga.plus/app/dev-ops/tutorials/what-is-a-cloud-server.html)

说明：你每点击一个右侧的命令，他就会在左侧进行输入，之后提示命令的用途和效果。这些命令包括了常用的文件、目录、系统、用户的操作，也给大家增加了 Git、Docker、Maven 的命令（右侧往下翻即可）

## 三、云系统环境安装

### 1. 环境选择

在你首次购买和设置云服务器的时候，它会让你选择需要安装的系统（也可以重置重新安装），安装完成后你就可以通过命令操作，部署 Docker 以及安装软件了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-03.png" width="550px">
</div>

这里比较推荐 Centos 7.6、7.9 或则 Ubuntu 24+，这两个系统，我已经做好了一键安装脚本，可以让你非常方便的把 Docker 以及一些常用的软件，全部安装完成。

### 2. 安装脚本

#### 2.1 Git 安装

**Centos**

```java
sudo yum install git
```

**Ubuntu**

```java
# sudo apt update
# sudo apt install nodejs npm
# node -v
# npm -v
```


```java
apt-get install git
```

#### 2.2 Docker + Portainer

```java
root@iv-ydw2iok0lcbw80bxaha0:~# ls
root@iv-ydw2iok0lcbw80bxaha0:~# cd /
root@iv-ydw2iok0lcbw80bxaha0:/# mkdir dev-ops
root@iv-ydw2iok0lcbw80bxaha0:/# ls
bin                cdrom    etc   lib64              media  proc  sbin                sys  var
bin.usr-is-merged  dev      home  lib.usr-is-merged  mnt    root  sbin.usr-is-merged  tmp
boot               dev-ops  lib   lost+found         opt    run   srv                 usr
root@iv-ydw2iok0lcbw80bxaha0:/# cd dev-ops/
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops# ls
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops# git clone https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install.git
Cloning into 'xfg-dev-tech-docker-install'...
remote: Enumerating objects: 181, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 181 (delta 20), reused 25 (delta 14), pack-reused 146 (from 1)
Receiving objects: 100% (181/181), 12.51 MiB | 1.26 MiB/s, done.
Resolving deltas: 100% (75/75), done.
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops# ls
xfg-dev-tech-docker-install
```

- 推荐；git clone https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install.git
- 备用；git clone https://github.com/fuzhengwei/xfg-dev-tech-docker-install.git

- 在 Linux 系统的根目录，通过命令创建一个空文件夹，进入文件夹，通过 git clone 检出代码。
- 这里有2个地址，如果 github.com 检出很慢，可以使用 gitcode.com 地址检出。

```java
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install# chmod +x ubuntu_run_install_docker_local.sh 
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install# ./ubuntu_run_install_docker_local.sh 
[INFO] 使用本地Docker安装脚本: ubuntu_install_docker.sh
[INFO] 设置可执行权限...
[INFO] 开始执行Docker安装脚本...
[INFO] 注意：安装过程可能需要root权限，如果需要会自动请求
-----------------------------------------------------------
[INFO] docker 环境安装脚本 By xiaofuge，建议使用 https://618.gaga.plus 优惠购买服务器，安装 Ubuntu 24.04 LTS 系统。
[INFO] 开始安装 Docker 环境...
[INFO] 检查系统信息...
内核版本: 6.8.0-55-generic
操作系统: Ubuntu 24.04 LTS
[INFO] 检测网络连接状态...
[INFO] 网络连接正常，可以访问: https://www.baidu.com
[INFO] 网络连接检测通过
...
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/xfg-studio/portainer:latest
1c2d6211944ced359ebec2e5d28b9cf30eec55bc781b386838c54abc944ed1f3
[INFO] Portainer安装成功！
[WARNING] 重要提示：请确保您的云服务器已开放9000端口！
-----------------------------------------------------------
Portainer访问方式：
1. 通过公网访问：http://您的服务器公网IP:9000
2. 首次访问需要设置管理员账号和密码
3. 登录后即可通过Web界面管理Docker容器
-----------------------------------------------------------
[INFO] 您可以使用Portainer来方便地管理Docker容器、镜像、网络和卷等资源
```

- Centos 执行 `chmod +x centos_run_install_docker_local.sh` `./centos_run_install_docker_local.sh`
- Ubuntu 执行 `chmod +x ubuntu_run_install_docker_local.sh` `./ubuntu_run_install_docker_local.sh`

执行的中间，他会有一些提示你的操作，你可以按照提示输入之后继续运行就好。安装到最后，Docker + Portainer 就安装完成了。注意，云服务器的访问，需要开放对应的端口在云服务器的安全组中找到出入站配置（也可以在云服务器官网搜，他都会提供文档）。

#### 2.3 软件安装（JDK、Maven）可选

在 xfg-dev-tech-docker-install 一键安装脚本中，还有提供 JDK、Maven 的安装。这个软件安全是为了在云服务器直接构建 Java 项目，如果你不需要，是完全可以不用安装的。

**Centos 安装**

```
/* Detailed source-code truncated for AI context efficiency. */
```

```java
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment# ls
jdk  maven
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment# cd maven/
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# ls
apache-maven-3.8.8.zip  install-maven.sh  remove-maven.sh
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# chmod +x install-maven.sh 
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# ./install-maven.sh 
[INFO] 开始Maven安装程序...
[INFO] 检测到系统: Ubuntu 24.04
[INFO] 检测到Java版本: 1.8.0_472
[INFO] 检查并安装依赖包...
[SUCCESS] Maven包验证通过
[INFO] 开始安装Maven 3.8.8 到: /usr/local/maven
[INFO] 解压Maven包...
[SUCCESS] Maven解压完成
[INFO] 配置环境变量...
[SUCCESS] 环境变量配置完成
[INFO] 环境变量已在当前会话中生效
[INFO] 验证安装...
[SUCCESS] Maven安装成功!
```

**Ubuntu 安装**

```java
sudo apt update
sudo apt install openjdk-8-jdk
  
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment# java -version
openjdk version "1.8.0_472"
OpenJDK Runtime Environment (build 1.8.0_472-8u472-ga-1~24.04-b08)
OpenJDK 64-Bit Server VM (build 25.472-b08, mixed mode)
```

```java
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# apt install maven
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically in
  
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# mvn --version
Apache Maven 3.8.7
Maven home: /usr/share/maven
...  
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-install/environment/maven# cd /usr/share/maven
root@iv-ydw2iok0lcbw80bxaha0:/usr/share/maven# ls
bin  boot  conf  lib  man
root@iv-ydw2iok0lcbw80bxaha0:/usr/share/maven# cd conf
root@iv-ydw2iok0lcbw80bxaha0:/usr/share/maven/conf# ls
logging  m2.conf  settings.xml  toolchains.xml  
```

Ubuntu 基本通过 apt 就可以完整这些软件的安装了。注意进入 conf 替换 settings.xml 文件带有阿里云 maven 镜像的地址。

地址：[https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install/blob/main/environment/maven/apache-maven-3.8.8/conf/settings.xml](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install/blob/main/environment/maven/apache-maven-3.8.8/conf/settings.xml)

#### 2.4 软件安装（MySQL、Redis）

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 执行提供好的脚本，即可完成各项软件的安装。其他的软件，也可以搜索教程安装。

### 3. 应用配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-04.png" width="750px">
</div>

- 云服务器环境 Docker + Portainer（管理docker的软件） 以及软件安装完成后，你就可以在你的 IntelliJ IDEA 的程序里配置对应的连接信息了。这样你的本地就可以连接到云服务器上的 Docker 里安装的 MySQL 了。
- Docker 是非常常用的软件，也是非常好用的软件，对于开发学习部署和卸载各类软件都非常方便，不会破坏本地环境。

## 四、项目部署

Docker 部署项目需要的是程序的镜像，镜像的目的是把一个程序运行所需的各类环境都给打包进行，等运行部署的时候直接执行即可。

所以，这里我们会通过各种方式来完成镜像的构建和部署，包括；
| 方案                                                         | 复杂度 |
| ------------------------------------------------------------ | ------ |
| 本地打包Jar + 云上构建镜像。                                 | ⭐️⭐️     |
| 云上打包Jar + 云上构建镜像。                                 | ⭐️⭐️⭐️    |
| 本地打包Jar + 本地构建镜像 + 上传到阿里云 Docker 镜像仓库 + 云上拉取构建 | ⭐️⭐️⭐️⭐️   |

### 1. 文件配置

#### 1.1 dockerfile

```java
# 基础镜像 openjdk:8-jre-slim
FROM registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用
ADD target/xfg-dev-tech-docker-deploy-app.jar /xfg-dev-tech-docker-deploy-app.jar

ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /xfg-dev-tech-docker-deploy-app.jar $PARAMS"]
```

- 这里配置了构建镜像的地址信息。

#### 1.2 build.sh

```java
# 普通镜像构建，随系统版本构建 amd/arm
docker build -t system/xfg-dev-tech-docker-deploy-app:1.0-SNAPSHOT -f ./Dockerfile .

# 兼容 amd、arm 构建镜像
# docker buildx build --load --platform liunx/amd64,linux/arm64 -t xiaofuge/xfg-frame-archetype-app:1.0 -f ./Dockerfile . --push
```

- 配置了构建镜像的名称。

### 2. 构建镜像

#### 2.1 本地打包Jar + 云上构建镜像

##### 2.1.1 打包jar 

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-05.png" width="750px">
</div>

- 在本地 install 构建项目 jar，target 目录下可以只保留项目的 jar 其他的删掉就可以。

##### 2.1.2 上传jar

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-06.png" width="750px">
</div>

- 把本地构建的jar，通过 sftp 把整个 xfg-dev-tech-deploy-app 上传到云服务器。

##### 2.1.3 构建镜像

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 通过这样的方式就把整个镜像构建出来，`docker images` 可以查看镜像列表，system/xfg-dev-tech-docker-deploy-app:1.0-SNAPSHOT 就是咱们构建的镜像。

#### 2.2 云上打包Jar + 云上构建镜像

##### 2.2.1 拉取项目

```java
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy# ls
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy# git clone https://github.com/fuzhengwei/xfg-dev-tech-docker-deploy.git
Cloning into 'xfg-dev-tech-docker-deploy'...
remote: Enumerating objects: 176, done.
remote: Counting objects: 100% (176/176), done.
remote: Compressing objects: 100% (87/87), done.
remote: Total 176 (delta 23), reused 175 (delta 22), pack-reused 0 (from 0)
Receiving objects: 100% (176/176), 75.84 KiB | 40.00 KiB/s, done.
Resolving deltas: 100% (23/23), done.
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy# ls
xfg-dev-tech-docker-deploy
```

- 通过 git clone 命令，拉取项目。

##### 2.2.2 打包jar

```java
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy/xfg-dev-tech-docker-deploy# ls
docs  pom.xml  README.md  xfg-dev-tech-docker-deploy-app
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy/xfg-dev-tech-docker-deploy# mvn clean install
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/2.7.12/spring-boot-starter-parent-2.7.12.pom
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for xfg-dev-tech-docker-deploy 1.0-SNAPSHOT:
[INFO] 
[INFO] xfg-dev-tech-docker-deploy ......................... SUCCESS [  0.219 s]
[INFO] xfg-dev-tech-docker-deploy-app ..................... SUCCESS [05:29 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:29 min
[INFO] Finished at: 2025-12-21T10:56:57+08:00
[INFO] ------------------------------------------------------------------------
root@iv-ydw2iok0lcbw80bxaha0:/dev-ops/xfg-dev-tech-docker-deploy/xfg-dev-tech-docker-deploy# ls
docs  pom.xml  README.md  xfg-dev-tech-docker-deploy-app  
```

- 进入到项目，通过 `mvn clean install` 打包项目 jar

##### 2.2.3 构建镜像

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 这样，就在云服务器把项目镜像构建出来了。

#### 2.3 阿里云 DockerHub

##### 2.3.1 账号申请

官网：[https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard](https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-07.png" width="750px">
</div>

- 如图所示，申请账号，创建个人的命名空间。步骤3、4可选。
- 之后你这里可以手动操作上传镜像，也可以走下面的流程自动操作。

##### 2.3.2 上传镜像

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-08.png" width="950px">
</div>

- 在项目下，有一个 push.sh 文件，可以把镜像推送到阿里云 DockerHub 镜像库。这样操作的目的是有个统一地方来维护镜像，各个云服务器都可以拉取部署了。
- 推送后，可以到仓库查看镜像 [https://cr.console.aliyun.com/cn-hangzhou/instance/repositories](https://cr.console.aliyun.com/cn-hangzhou/instance/repositories)

### 3. 项目部署

#### 3.1 脚本说明

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-09.png" width="950px">
</div>

- 这里的镜像名称，要修改成你的镜像名称。

#### 3.2 上传脚本

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-10.png" width="950px">
</div>

- 上传项目下的部署脚本到云服务器，dev-ops 创建个文件夹。

#### 3.3 执行部署

```
/* Detailed source-code truncated for AI context efficiency. */
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-deploy-11.png" width="950px">
</div>

- 部署后，就可以访问服务看最终的效果了！**

---

### Md Road Map Docker Idea (`docs/md/road-map/docker-idea.md`)

---
title: Docker IntelliJ IDEA
lock: need
---

# Docker WEB IntelliJ IDEA —— 随时随地打开浏览器就能写代码！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=1556278601&bvid=BV1P142187rg&cid=1636946677&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

我遇到过不少粉丝伙伴因为自己是老 Windows 电脑，部署项目费劲的问题。因为本身 Java 开发完成以后就是部署到 Linux 服务器的，而 Windows 压根不是 Linux 系统。所以不是装虚拟机，就是装 Docker 来模拟这些环境，但很多时候都差强人意，尤其是配置低的 Windows 又跑不动，这咋办！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-00.png" width="150px"/>
</div>

**死鬼，我就知道你有很多办法！**

嘿嘿，是的，小傅哥又给你带来一个新方法：”在 Linux 安装一个 IntelliJ IDEA！“ 并且可以在线执行代码、构建项目、打包程序。这不美滋滋，尤其是对有学习项目诉求的伙伴，不就可以随时随地学习自己的项目了吗！

>好啦，接下来小傅哥就带着你安装下。文末提供了本次安装的相关脚本。

## 一、前置说明

- 一台云服务器，最低 2c4g [https://618.gaga.plus](https://618.gaga.plus ) —— 价格比较实惠。
- 安装 Docker、Docker Compose 教程：[https://bugstack.cn/md/road-map/docker.html](https://bugstack.cn/md/road-map/docker.html)

```java
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://dc.j8.work", "https://docker.1panel.live"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```

- 如果拉取镜像失败，可以配置下以上地址。

## 二、安装脚本

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-01.png" width="450px"/>
</div>

- 地址：[https://gitcode.net/KnowledgePlanet/xfg-dev-tech-docker-idea](https://gitcode.net/KnowledgePlanet/xfg-dev-tech-docker-idea)
- 说明：小傅哥这里为你提供了搭建 Docker IDEA 的操作脚本，并配有 JDK、Maven，这样可以更加方便我们构建项目。

## 三、执行安装

### 1. 上传脚本

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-02.png" width="650px"/>
</div>

- 下载项目后，把本地的配置文件传到云服务器端。注意是 root 目录下。也就是 `~` 这里。

### 2. 解压文件

#### 2.1 jdk

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-04.png" width="650px"/>
</div>

```java
[root@lavm-aqhgp9nber java]# tar -zxvf jdk-8u202-linux-x64.tar.gz 
```

- 这个解压后是为了映射到 Docker IntelliJ IDEA 下的。

#### 2.2 maven

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-05.png" width="650px"/>
</div>

```java
[root@lavm-aqhgp9nber maven]# unzip apache-maven-3.8.8.zip 
```

- 可选不非得加压，因为我们可以直接把 `maven .m2` 下的 `settings.xml` 映射到  Docker IntelliJ IDEA 下。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-06.png" width="650px"/>
</div>

```java
[root@lavm-aqhgp9nber maven]# ls -a
.  ..  apache-maven-3.8.8.zip  install-maven.sh  .m2  remove-maven.sh
```

### 3. 授权文件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-03.png" width="850px"/>
</div>

```java
chmod -R 777 projector-user/
```

- 给整个文件夹包括文件夹下的其他文件一起授权。
- 授权后检查当前文件夹 `projector-user` 和文件夹以下的 java、maven 文件夹。

### 4. 执行安装 

```java
# 命令执行 docker-compose -f docker-compose.yml up -d
# 以下这些都可以做 WEB IDEA 安装。在下面替换就可以。
# docker pull registry.jetbrains.team/p/prj/containers/projector-clion
# docker pull registry.jetbrains.team/p/prj/containers/projector-datagrip
# docker pull registry.jetbrains.team/p/prj/containers/projector-goland
# docker pull registry.jetbrains.team/p/prj/containers/projector-idea-c
# docker pull registry.jetbrains.team/p/prj/containers/projector-idea-u
# docker pull registry.jetbrains.team/p/prj/containers/projector-phpstorm
# docker pull registry.jetbrains.team/p/prj/containers/projector-pycharm-c
# docker pull registry.jetbrains.team/p/prj/containers/projector-pycharm-p

version: '3.9'
services:
  intellij-idea:
    image: registry.jetbrains.team/p/prj/containers/projector-idea-c
    container_name: intellij-idea
    ports:
      - "8887:8887"
    volumes:
      - ~/projector-user:/home/projector-user
      - ~/projector-user/maven/.m2/settings.xml:/home/projector-user/.m2/settings.xml
    tty: true
    stdin_open: true
    restart: unless-stopped  # 这将确保容器在失败时自动重启
```

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-08.png" width="950px"/>
</div>

- 执行脚本 `docker-compose -f docker-compose.yml up -d`
- 安装完成后记得在云服务器开放端口 `8887`

### 5. 测试项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-07.png" width="550px"/>
</div>

- 通过 `git clone` 检出项目地址 github/gitee/gitcode ，这样在projector-user 下就可以看到你的项目了。
- 这个是用于 WEB IDEA 打开的项目，当然也可以在 WEB IDEA 创建信息项目。

## 四、访问测试

地址：[http://117.72.37.243:8887/](http://117.72.37.243:8887/) 

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-09.png" width="950px"/>
</div>

- 接下来你就可以在网页端，操作自己的项目了，想怎么玩就怎么玩，和本地效果是一样的。
- 这对于新人伙伴学习编程太有用了，直接在云服务器都能打包部署了。

---

### Md Road Map Docker Install (`docs/md/road-map/docker-install.md`)

---
title: Docker 环境配置（一键安装）
lock: need
---

# Docker 环境配置（一键安装）

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=114695709132495&bvid=BV1oaNazEEf5&cid=30537353073&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

说实话，做项目不上线，等于吃面不配蒜🧄，效果少一半！面试官也说：“所有做Java编程项目，没有上线云服务器的，一律当玩具看！” 是呀，做完项目不上线，是不你做的项目没法运行，是个小卡拉米练手的？🤔 那怎么办？

其实，上线云服务器非常非常简单，而且云服务器价格也非常非常便宜！趁着618活动月，**28块钱**，都能买一年的云服务器☁️，干嘛不上车！

<div align="center">
    <img src="https://bugstack.cn/images/system/zsxq/xingqiu-231018-00.png" width="200px">
</div>

**啥是云服务器？**

云服务器，就等同于自己的另外一个电脑💻，在另外一台电脑部署 redis、mysql、mq等，本地电脑连接过去使用。尤其是 Windows 电脑用户，真心建议搞个云服务器，否则你会浪费非常多的时间这套 Windows 适配问题。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-06.png" width="650px">
</div>

这样有了云服务器，就可以不用嚯嚯本地电脑了，安装了卸，卸了安装，把自己本机电脑环境弄的乱码起糟，全是费时费力的事。有这精力，不如用一台云服务器部署环境，开发完成项目后，再上线云服务器。既节省本地电脑资源，又锻炼了云服务器操作，起步一举两得！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-00.png" width="150px">
</div>

不过，放心！别担心你不会用云服务器，因为小傅哥已经给你准备了一件安装云服务器环境的脚本，和各类部署环境和构建项目的视频。**即使是小卡拉米，也能跟着学习下来。**

> 🧧小傅哥还提供了非常多的编程实战项目，包括；业务的、组件的、AI的、源码的、轮子的，可以关注公众号「bugstack虫洞栈」回复「星球」加入。

## 一、优惠云服务器地址

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-01.png" width="400px">
</div>

- 购买地址：[https://618.gaga.plus](https://618.gaga.plus)
- 购买地址：[https://618.gaga.plus](https://618.gaga.plus)
- 购买地址：[https://618.gaga.plus](https://618.gaga.plus)

**我适合买哪个服务器？**

- 2c2g 1年，28￥，可部署一套 docker、mysql、redis、SpringBoot 单体项目，用于替代本地电脑的环境部署。
- 2c4g 1年（非常推荐3年），109￥，可部署一套 docker、mysql、redis、rabbitmq、xxl-job、SpringBoot 分布式微服务项目。 
- 2c8g 1年，328￥，适合部署小傅哥星球社群[大部分项目](https://bugstack.cn/md/zsxq/material/student-learn-advanced.html)，可以完成多个微服务项目部署。

注意📢：购买选择系统时，推荐系统镜像，**centos 7.9**

>如果自己账号不是新人身份，可以自己注册个新账号，用家里人JD扫码认证一下即可。

🎁 礼物赠送，购买2c4g 3年的，赠送Joy公仔，邮寄到家！购买后，联系小傅哥（微信：fustack）

## 二、一键部署脚本

小傅哥，这里为你准备一键安装 Docker 环境的脚本文件，你可以非常省心的完成 Docker 部署。使用方式如下。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-02.png" width="650px">
</div>

- **地址**：<https://github.com/fuzhengwei/xfg-dev-tech-docker-install>
- **地址**：<https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install>

本文档介绍如何执行项目中的各个脚本，包括权限设置和执行步骤。

### 1. 上传脚本&设置权限

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-03.png" width="650px">
</div>

- ssh 工具，推荐 termius。[https://bugstack.cn/md/road-map/tool.html](https://bugstack.cn/md/road-map/tool.html) 免费的就够用，带有 sftp 工具。
- 左侧是云服务器空间 root 下，右侧是本地环境。可以把整个文件夹全部拖到云服务器。
- 另外，也可以在云服务器执行 `sudo yum install git` 安装 Git，通过 git clone 拉取脚本。

在执行任何脚本之前，需要先为脚本文件添加可执行权限：

```
# 为所有脚本添加可执行权限
chmod +x environment/jdk/install-java.sh
chmod +x environment/jdk/remove-java.sh
chmod +x run_install_docker_local.sh
chmod +x run_install_software.sh
chmod +x install-maven.sh
chmod +x remove-maven.sh

```
或者一次性为所有脚本添加权限：

```
find . -name "*.sh" -type f -exec chmod +x {} \;
```

### 2. JDK 安装脚本

#### 2.1 安装 JDK

脚本位置： environment/jdk/install-java.sh

功能： 支持安装 JDK 8 和 JDK 17

执行方式：

```
# 交互式安装（推荐）
sudo ./environment/jdk/install-java.sh

# 指定版本安装
sudo ./environment/jdk/install-java.sh -v 8    # 安装 JDK 8
sudo ./environment/jdk/install-java.sh -v 17   # 安装 JDK 17

# 强制安装（覆盖已有安装）
sudo ./environment/jdk/install-java.sh -f -v 8

# 静默安装
sudo ./environment/jdk/install-java.sh -q -v 8

# 自定义安装目录
sudo ./environment/jdk/install-java.sh -d /opt/java -v 8
```
注意事项：

- 需要 root 权限执行
- 脚本会提示手动下载 JDK 包到 /dev-ops/java 目录
- 支持的版本：JDK 8 (1.8.0_202) 和 JDK 17 (17.0.14)
- 安装完成后环境变量会自动配置

#### 2.2 卸载 JDK

脚本位置： environment/jdk/remove-java.sh

功能： 彻底清理 JDK 安装和环境配置

执行方式：

```
# 交互式删除（推荐）
sudo ./environment/jdk/remove-java.sh

# 强制删除
sudo ./environment/jdk/remove-java.sh -f

# 静默删除
sudo ./environment/jdk/remove-java.sh -f -q

# 指定安装目录删除
sudo ./environment/jdk/remove-java.sh -d /opt/java

# 删除时不备份配置文件
sudo ./environment/jdk/remove-java.sh --no-backup
```
注意事项：

- 需要 root 权限执行
- 会自动备份配置文件（除非使用 --no-backup）
- 清理系统和用户级环境变量配置

### 2.3 Maven 安装脚本

#### 2.3.1 安装 Maven

脚本位置：`environment/maven/install-maven.sh`

功能：自动安装 Apache Maven 3.8.8

执行方式：

```bash
# 交互式安装（推荐）
sudo ./environment/maven/install-maven.sh

# 自定义安装目录
sudo ./environment/maven/install-maven.sh -d /opt/maven

# 使用本地Maven包
sudo ./environment/maven/install-maven.sh -p /path/to/apache-maven-3.8.8.zip

# 强制安装（覆盖已有安装）
sudo ./environment/maven/install-maven.sh -f

# 静默安装
sudo ./environment/maven/install-maven.sh -q

# 强制静默安装
sudo ./environment/maven/install-maven.sh -f -q
```

### 3. Docker 安装脚本

脚本位置： run_install_docker_local.sh

功能： 使用本地的 install_docker.sh 脚本安装 Docker

执行方式：

```
# 执行 Docker 安装
./run_install_docker_local.sh
```
注意事项：

- 脚本会自动检查 install_docker.sh 文件是否存在
- 如果需要 root 权限会自动请求
- 安装完成后会询问是否安装 Portainer 容器管理界面
- Portainer 访问地址： http://服务器IP:9000

### 4. 软件安装脚本

脚本位置： run_install_software.sh

功能： 使用 Docker Compose 安装各种开发软件

执行方式：

```
# 执行软件安装
sudo ./run_install_software.sh
```

支持的软件：

- nacos - 服务注册与发现
- mysql - 数据库
- phpmyadmin - MySQL 管理界面
- redis - 缓存数据库
- redis-admin - Redis 管理界面
- rabbitmq - 消息队列
- elasticsearch - 搜索引擎
- logstash - 日志处理
- kibana - 日志分析界面
- xxl-job-admin - 任务调度
- prometheus - 监控系统
- grafana - 监控面板
- ollama - AI 模型服务
- pgvector - 向量数据库
- pgvector-admin - 向量数据库管理界面
  注意事项：

- 需要 root 权限执行
- 需要先安装 Docker 和 docker-compose
- 脚本会检查磁盘空间并显示预计占用
- 支持选择原始配置或阿里云镜像配置
- 可以多选软件进行批量安装

### 5. 常见问题

#### 5.1 权限问题

如果遇到权限拒绝错误：

```
# 确保脚本有执行权限
ls -la *.sh
# 如果没有 x 权限，重新添加
chmod +x script_name.sh
```

#### 5.2 环境变量生效

JDK 安装后，环境变量在当前会话中已生效，新开终端需要：

```
# 重新加载配置
source /etc/profile
# 或者重新登录
```

#### 5.3 Docker 相关

确保 Docker 服务正在运行：

```
# 检查 Docker 状态
sudo systemctl status docker
# 启动 Docker 服务
sudo systemctl start docker
```

### 6. 执行顺序建议

1. 首先安装 JDK （如果需要）：

   ```
   sudo ./environment/jdk/install-java.sh -v 8
   ```

2. 然后安装 Docker ：

   ```
   ./run_install_docker_local.sh
   ```

3. 然后安装 Docker ：

   ```
   ./install-maven.sh
   ```

4. 最后安装开发软件 ：

   ```
   sudo ./run_install_software.sh
   ```
   按照以上步骤，您就可以成功执行所有脚本并搭建完整的开发环境。

### 7. 安装演示

#### 7.1 docker 安装

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-04.png" width="650px">
</div>

```java
[root@xiaofuge ~]# ls
run_install_docker_local.sh
[root@xiaofuge ~]# chmod +x run_install_docker_local.sh 
[root@xiaofuge ~]# ./run_install_docker_local.sh 
```

- 执行完 `./run_install_docker_local.sh ` 全程会自动化安装，如果已经过 docker 会提示是否卸载。使用起来非常方便。

#### 7.2 软件安装

```java
[root@xiaofuge dev-ops]# ls
install_docker.sh  README.md  run_install_docker_local.sh  run_install_docker.sh  run_install_software.sh  software
[root@xiaofuge dev-ops]# chmod +x run_install_software.sh 
[root@xiaofuge dev-ops]# ls
install_docker.sh  README.md  run_install_docker_local.sh  run_install_docker.sh  run_install_software.sh  software
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-install-07.png" width="550px">
</div>

- 安装时候可以选择需要安装的软件，重复安装也会提示卸载。

---

### Md Road Map Docker What (`docs/md/road-map/docker-what.md`)

---
title: Docker 是什么？
lock: need
---

# Docker 是什么？

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

**好用，真的好用！** 自从使用 Docker 后，我可以非常简单的`安装`、`使用`、`卸载`各类所需的软件，如；MySql、Redis、RabbitMQ、XXL-Job、FRP，等一些列开发环境和我自己开发的好的项目进行上线发布。以前一个MySql安装到卸载，可能半天时间都没了。但有 Docker 后，我自己既可以是开发工程师也是可以是软件实施工程师。因为他可以一行脚本即可完成所有的操作，脚本在，环境就在，服务就在。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-00.gif" width="200px">
</div>

**那 Docker 是什么呢？**

Docker 是什么，其实来自于 Docker 的图标已经说明。Docker 的图标是一条鲸鱼 🐳一样的大船，上面摆放了很多集装箱。你可以把这些集装箱当做是一个个不同的应用程序，虽然不同但可以统一用一套集装箱（脚本命令）承载，并承放在统一一条大船上（环境上）。而且这些集装箱都有自己的编号ID（有自己的IP）互相隔离，不受影响。

Docker 是一个用于开发、发布和运行应用程序的开放平台。Docker 可让您将应用程序与基础架构分离，以便快速交付软件。借助 Docker，您可以像管理应用程序一样管理基础架构。通过利用 Docker 的发布、测试和部署代码方法，您可以显著减少编写代码和在生产中运行代码之间的延迟。

官网：[https://www.docker.com/](https://www.docker.com/)
文档：[https://docs.docker.com/get-started/docker-overview/](https://docs.docker.com/get-started/docker-overview/)

## 一、Docker 安装在哪

Docker 可以安装在 Windows + wsl2、Mac、Linux，支持 ARM、AMD 架构。它可以通过软件下载安装和执行脚本命令安装，也可以通过云服务器提供的镜像直接购买云服务器时选择使用。我们可以看下 Docker 和虚拟机安装在操作系统上的关系来了解 Docker 的安装位置。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-02.png" width="550px">
</div>

与虚拟机的安装使用相比，Docker 会把应用所需的依赖、函数库、甚至其他的软件应用可以一起打包成一个镜像，这样在应用程序运行时，就可以直接调用本地函数库，然后和 Linux 内核进行通信。有了这样的设计，你也就不需要关心每一个应用所需的环境都是啥了，也不用为每一个应用安装各类环境到 Linux 或者虚拟机了。也就做到了跨系统的运行。这有点类似于 Java 的 JVM 虚拟机。

- 本地安装：[https://www.docker.com/](https://www.docker.com/) - 下载 Mac、Windows 你需要的版本进行安装。
- 云服务器：[https://bugstack.cn/md/road-map/docker.html](https://bugstack.cn/md/road-map/docker.html) - centos 7.9 其他的也都类似操作即可。

>安装完成后都可以通过命令操作，安装、部署、卸载软件。文末提供了教程链接。

## 二、Docker 怎么工作

Docker 为了屏蔽软件使用差异，会统一对这些软件进行镜像打包，把一个软件所需的各类环境都打包到镜像中。我们在使用的时候，就是使用各类平台提供好的软件镜像，进行服务部署。同样的我们也可以作为镜像提供方，把我们的应用程序 SpringBoot、React、VUE 等，打包成镜像，让我们在其他地方，如云服务器进行部署。或者提供给全网的人员，进行部署使用。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-03.png" width="750px">
</div>

如图，这是一整套的，本地拉取镜像、部署环境、开发代码、发布镜像，再到云服务器拉取镜像、部署项目和环境的过程。在这个过程中，我们也可以借助于如 Github Action 完成镜像的构建和发布，还可以在云服务器上直接构建镜像，减少了拉取拉取的过程。

> 你可以理解为，Docker 就是一个中心和一个客户端，中心管理镜像，客户端拉取使用或者构建发布镜像。

## 三、Docker 命令说明

Docker 的操作是通过脚本命令配置和执行完成使用，不过不用害怕命令😱，命令是最简单、直接、可靠的方式。当你习惯命令以后，你会很喜欢它，并且知道只要执行这个命令就一定会有结果，而不像被软件包装后，不确定是软件的问题还是命令的问题。

Docker 安装软件分为直接使用和通过 Docker Compose 脚本。直接使用如；`docker run -d --restart=always --name portainer -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer` 这条命令会自动拉取和执行脚本。不过对于更大的项目部署，Docker Compose 脚本更好用。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-04.png" width="750px">
</div>

- 如图，是整个 Docker Compose 在配置一套执行脚本后，各个脚本的核心用途。当然 Docker Compose 还有不少的命令，比如容量的限制、端口的处理、默认的命令等，都是可以操作的，凡是你想的合理的，它都可以支持。
- 特别注意，安装到云服务器的docker部署的应用，外部访问需要走公网IP:Port端口，之后这个端口要在安全组打开。这样就类似于你再本地自己的电脑发，访问另外一台电脑上的服务了。
- 如果在使用中遇到其他命令不理解的，可以让 [openai](https://openai.itedus.cn) 解释。

## 四、Docker 实操教程

此外，为了大家更好的使用 Docker 搭建各类环境，小傅哥为大家准备好了文档和视频。可以放心食用。

- 文档：[https://bugstack.cn/md/road-map/docker.html](https://bugstack.cn/md/road-map/docker.html) - 这是一个系列，你可以从左侧目录选择阅读。
- 视频：[https://www.bilibili.com/video/BV1xw411W7xf](https://www.bilibili.com/video/BV1xw411W7xf) - 对应一整套的视频，手把手操作。

---

### Md Road Map Docker (`docs/md/road-map/docker.md`)

---
title: Docker 环境配置（手动安装）
lock: need
---

# Docker 环境配置（手动安装）

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=924100393&bvid=BV1ET4y1b7Ez&cid=1413251533&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

- 官网：[https://www.docker.com](https://www.docker.com/) - Mac、Windows、Linux
- 介绍：Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中，然后发布到任何流行的 Mac、Linux或Windows操作系统的机器上，也可以实现虚拟化。容器是完全使用沙箱机制，相互之间不会有任何接口。总之它加快构建、共享和运行现代应用程序的速度。

## 一、基础安装

### 1. 查看系统的内核版本

```shell
uname -r
```

```java
4.18.0-80.11.2.el8_0.x86_64
```

- `uname -r`
- x86 64位系统，如果是32位是不能安装 docker 的

### 2. yum 更新到最新版本

```shell
sudo yum update
```


```java
Last metadata expiration check: 1:15:10 ago on Sat 27 Nov 2021 04:22:53 PM CST.
Dependencies resolved.
Nothing to do.
Complete!
```

- `sudo yum update`
- 看到显示 `Complete` 就代表完成了，整个过程需要 5-10 分钟左右

注意：可能会更新失败，那就操作以下指令

~~~~bash
## 建议备份当前的 yum 源配置，以防万一需要恢复
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

## 从阿里云下载 CentOS 7 的 yum 源配置文件并替换现有的配置
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

## 清理旧的缓存并生成新的缓存
sudo yum clean all
sudo yum makecache

## 再次更新
sudo yum update
~~~~



### 3. 安装Docker所需的依赖包

```java
[root@CodeGuide ~]# sudo yum install -y yum-utils device-mapper-persistent-data lvm2
Last metadata expiration check: 1:16:16 ago on Sat 27 Nov 2021 04:22:53 PM CST.
Package yum-utils-4.0.21-3.el8.noarch is already installed.
Package device-mapper-persistent-data-0.9.0-4.el8.x86_64 is already installed.
Package lvm2-8:2.03.12-10.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to
```

- `sudo yum install -y yum-utils device-mapper-persistent-data lvm2`
- 看到显示 `Complete` 就代表完成了，整个过程需要 1-3 分钟左右

### 4. 设置Docker的yum的源

```shell
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
```

```java
Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
```

- sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 鉴于国内网络问题，强烈建议使用国内源。以下是阿里云的软件源。**如果是海外如AWS云就不要设置yum源**

```bash
sudo yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
```

### 5. 查看仓库所有Docker版本

```java
[root@CodeGuide ~]# yum list docker-ce --showduplicates | sort -r
Installed Packages
docker-ce.x86_64               3:20.10.9-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.8-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.7-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.6-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.5-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.4-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.3-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.2-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.1-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:20.10.11-3.el8                docker-ce-stable 
docker-ce.x86_64               3:20.10.11-3.el8                @docker-ce-stable
docker-ce.x86_64               3:20.10.10-3.el8                docker-ce-stable 
docker-ce.x86_64               3:20.10.0-3.el8                 docker-ce-stable 
docker-ce.x86_64               3:19.03.15-3.el8                docker-ce-stable 
docker-ce.x86_64               3:19.03.14-3.el8                docker-ce-stable 
docker-ce.x86_64               3:19.03.13-3.el8                docker-ce-stable 
Docker CE Stable - x86_64                       7.1 kB/s | 3.5 kB     00:00    
Available Packages
```

-  yum list docker-ce --showduplicates | sort -r
- 这里可以看到你能安装的最新版本

### 6. 安装Docker

```java
[root@CodeGuide ~]# sudo yum install docker-ce
[root@CodeGuide ~]# 推荐；sudo yum install -y docker-ce-25.0.5 docker-ce-cli-25.0.5 containerd.io
```

- 安装默认最新版本的 Docker `最新版本可能有坑，最好指定版本安装`

```java
[root@CodeGuide ~]# sudo yum install <FQPN>
```

- 安装指定版本，例如：`yum install -y docker-ce-25.0.5 docker-ce-cli-25.0.5 containerd.io`

### 7. 安装Docker-Compose

#### 7.1 正常安装

**官网地址**

```shell
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```

**镜像地址**

```shell
# 指定路径【推荐】
sudo curl -L https://gitee.com/fustack/docker-compose/releases/download/v2.24.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 设置权限
sudo chmod +x /usr/local/bin/docker-compose
```

#### 7.2 离线安装

```shell
# 下载；docker-compose-`uname -s`-`uname -m` 查看版本；https://github.com/docker/compose/releases/tag/v2.18.1
# 重命名
mv docker-compose-linux-x86_64 docker-compose
# 加入执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 查看docker-compose版本
docker-compose -v
```

```java
sudo chmod +x /usr/local/bin/docker-compose
docker-compose -v
Docker Compose version v2.18.1
```

- 安装后就可以使用 compose 命令了；`docker-compose -f environment-docker-compose.yml up -d`

### 8. 启动Docker并添加开机自启动

```java
[root@CodeGuide ~]# sudo systemctl start docker
```

- 启动 Docker

```java
[root@CodeGuide ~]# systemctl enable docker
```

- 设置开机启动 Docker

```java
sudo systemctl restart docker
```

- 重启 Docker 命令

### 9. 查看 Docker 版本

```java
[root@CodeGuide ~]# docker --version
Docker version 20.10.11, build dea9396
```

### 10. 卸载 Docker

```java
[root@CodeGuide ~]# sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
```

### 11. Docker 常用命令

```java
[root@CodeGuide ~]# docker --help				#Docker帮助
[root@CodeGuide ~]# docker --version			#查看Docker版本
[root@CodeGuide ~]# docker search <image>		#搜索镜像文件，如：docker search mysql
[root@CodeGuide ~]# docker pull <image>		#拉取镜像文件， 如：docker pull mysql
[root@CodeGuide ~]# docker images				#查看已经拉取下来的所以镜像文件
[root@CodeGuide ~]# docker rmi <image>		#删除指定镜像文件
[root@CodeGuide ~]# docker run --name <name> -p 80:8080 -d <image>		#发布指定镜像文件
[root@CodeGuide ~]# docker ps					#查看正在运行的所有镜像
[root@CodeGuide ~]# docker ps -a				#查看所有发布的镜像
[root@CodeGuide ~]# docker rm <image>			#删除执行已发布的镜像
```

### 12. 设置国内源

1. 【推荐】1panel 提供了镜像源 [https://status.1panel.top/status/docker](https://status.1panel.top/status/docker) - `直接进去就可以找到最新的镜像源`
2. 阿里云提供了镜像源：[https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors) - 登录后你会获得一个专属的地址。

使用以下命令来设置 Docker 国内源：- 或者你可以通过 `vim /etc/docker/daemon.json` 进入修改添加 registry-mirrors 内容后重启 Docker

```yaml
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://***替换为你的地址***.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```

可用镜像检测：[https://status.1panel.top/status/docker](https://status.1panel.top/status/docker)

#### 12.1 本地Docker软件配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-01.png" width="850px">
</div>

```yaml
{ "registry-mirrors" : [
    "https://docker.1panel.live",
    "https://dc.j8.work",
    "https://docker.m.daocloud.io"
  ],
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "20GB"
    }
  },
  "experimental": false,
  "features": {
    "buildkit": true
  }
}
```

这个命令会创建一个 `/etc/docker/daemon.json` 文件，并将国内源的配置写入其中。然后你只需要重启 Docker 服务即可使配置生效，可以通过运行 `sudo systemctl restart docker` 命令来重启 Docker 服务。

**解决目前Docker Hub国内无法访问方法**

自从2023年5月中旬，著名Docker 容器平台：`hub.docker.com`  “不知” 何种原因国内均无法正常访问了。

这样对国内服务器拉取Docker仓库影响比较大。不过得亏国内有Docker Hub镜像平台。有付费的，有免费的！

#### 12.2 Linux 配置 Docker 镜像

```yaml
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
  "https://docker.1panel.live",
  "https://dc.j8.work",
  "https://docker.m.daocloud.io",
  "https://dockerproxy.com",
  "https://docker.mirrors.ustc.edu.cn",
  "https://docker.nju.edu.cn"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```

- 参考链接：https://cloud.tencent.com/developer/article/2301228

### 13. 远程连接 - 不推荐

```shell script
vim /lib/systemd/system/docker.service
```

```shell script
[Unit]Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
Wants=docker-storage-setup.service
Requires=docker-cleanup.timer

[Service]
Type=notify
NotifyAccess=main
EnvironmentFile=-/run/containers/registries.conf
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash
Environment=DOCKER_HTTP_HOST_COMPAT=1
Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
ExecStart=/usr/bin/dockerd-current \
          --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
          --default-runtime=docker-runc \
          --exec-opt native.cgroupdriver=systemd \
          --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
          --init-path=/usr/libexec/docker/docker-init-current \
          --seccomp-profile=/etc/docker/seccomp.json \
          -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock \
          $OPTIONS \
          $DOCKER_STORAGE_OPTIONS \
          $DOCKER_NETWORK_OPTIONS \
          $ADD_REGISTRY \
          $BLOCK_REGISTRY \
          $INSECURE_REGISTRY \
          $REGISTRIES
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
Restart=on-abnormal
KillMode=process

[Install]
WantedBy=multi-user.target
```

- 添加：`-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock \`

```shell script
# 加载
systemctl daemon-reload
# 重启
systemctl restart docker
# 测试
curl http://127.0.0.1:2375/info
```

- 之后你就可以打开 IDEA 的 Services 配置 Docker 了；`tcp://180.76.138.**:2375` 验证连接后就可以使用了。

### 14. 卸载Docker

```shell
/Applications/Docker.app/Contents/MacOS/Docker --uninstall
```

---

### Md Road Map Draw.Io (`docs/md/road-map/draw.io.md`)

---
title: draw.io + ai agent
lock: need
---

# draw.io + ai Agent，确实打开新思路

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=115652731865787&bvid=BV13ZSaBqE9G&cid=34460795162&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

又到年底了，又要必不可少的开始画图做PPT述职啦 😂，述职的好坏和年终奖都有可能挂钩！这对天天写代码大部分的程序员👨🏻‍💻来说是一件非常头疼的事，但好在这次可以使用个**神器**！

<div align="center">
	<img src="https://bugstack.cn/images/article/project/chatgpt/openai-01.jpg" width="150px"/>
</div>

**Ai Agent 会结合到各个场景！**

可以想象，将来我们使用的各种工具，都会很方便的以标准的协议方式结合到 AI Agent 智能体。这就像小傅哥，25年，年初开始做 Ai Agent 时，对一个智能体的执行过程，是需要自己进行分析，设计，实现的（`那时候我就在讲，Agent 也会出标准框架`）。到了年中的时候 Google ADK 除了 0.1.0 最初的版本，年尾发布了 0.4.0，这个框架提供了构建智能体的最基本框架，可以整合 Spring AI、Langchain4j 快速构建智能体。

>Spring AI、Langchain4j 提供的是 AI 封装能力，Google ADK 提供的是 Agent 执行能力（并行、循环、串行）的组装和使用。

未来（甚至不会太久），各个软件与 Ai Agent 的对接会变得非常容易，你手里用到的各项软件，都可以很方便的添加上智能体的能力。就像，我们现在用到的 `trae.ai`、`Cursor`，在以后 Ai Agent 基础能力成熟后，在结合 `Visual Studio Code` 给出软件对接标准协议，那么任何一个人都可以快速的搭建出一个智能体编码工具。除此之外，其他的软件也都会逐步提供出这样的能力。

扩展的思路分析完毕，小傅哥这次先带着大家了解下，draw.io 是怎么与 Ai 结合使用的。

>🧧 文末提供了小傅哥所有编程实战项目获取方式，一次加入即可获得19个已完结的和本次新开展的。

## 一、关于 draw.io

draw.io 是一个用于绘制通用图表的 JavaScript 客户端编辑器。

官网：[https://www.drawio.com/](https://www.drawio.com/)
代码：[https://github.com/jgraph/drawio](https://github.com/jgraph/drawio)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-01.png" width="950px"/>
</div>

我所有的这类的绘图，都来自于使用 draw.io 完成（[bugstack.cn](https://bugstack.cn) 还有很多绘图）。它可以下载到本地使用，也可以在网页使用。如果你是开发人员，还可以使用它的开发组件引入到自己的程序中进行使用。也正因如此，有了 Ai Agent 能力的结合，一种是通过 MCP，另外一种是直接通过扩展功能，直接在 draw.io 二开上完成。接下来小傅哥会分别介绍这两种方式以及使用。

## 二、MCP 方式对接

MCP（Model Context Protocol）是用于解决 AI 与服务接口通信的标准模型上下文协议，该协议通过标准化通信方式，使AI应用程序能够访问和使用实时数据、执行操作，从而克服了模型训练数据的局限性。 你可以将MCP想象成AI应用程序的“USB-C接口”，它提供了一个标准化的方法，让AI模型能够连接各种外部资源。

**Draw.io Model Context Protocol (MCP) Server**，就是基于此协议实现的对接 Draw.io 的 MCP 服务。我们可以使用这样一套服务，把 AI 与 Draw.io 建立起使用链接。

源码：[https://github.com/lgazo/drawio-mcp-server](https://github.com/lgazo/drawio-mcp-server)

### 1. 插件安装

- 谷歌浏览器：[https://chromewebstore.google.com/detail/drawio-mcp-extension/okdbbjbbccdhhfaefmcmekalmmdjjide](https://chromewebstore.google.com/detail/drawio-mcp-extension/okdbbjbbccdhhfaefmcmekalmmdjjide)
- 火狐浏览器：[https://addons.mozilla.org/en-US/firefox/addon/drawio-mcp-extension/](https://addons.mozilla.org/en-US/firefox/addon/drawio-mcp-extension/)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-02.png" width="650px"/>
</div>

安装完成后，可以看到这样一个小插件（右侧插件文件里可以点击让常驻浏览器），之后后面可以等着使用（继续下面的步骤）。

### 2. 配置服务

```java
{
	"mcpServers": {
		"drawio": {
			"command": "npx",
			"args": [
			  "-y",
        "drawio-mcp-server"
			]
		}
	}
}
```

#### 2.1 trae.ai - 也可以其他的

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-03.png" width="650px"/>
</div>

#### 2.2 spring ai

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-04.png" width="650px"/>
</div>

### 3. 使用服务

首先打开：[https://app.diagrams.net/#](https://app.diagrams.net/)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-05.png" width="950px"/>
</div>

- 对接上之后，你就可以在右侧提问了。之后他就可以实时的出设计图。`受限于MCP服务对接，它不是在 Draw.io 上扩展，会缺少一些交互和判断，画图有时候会有重叠。`
- 不过，这个方式的好处是，你可以结合自己的代码，拖进去，让它直接出架构图、流程图、模型图等。之后在自己做一些调整。

## 三、软件方式使用

现在 Github 上有很多基于 Draw.io 的二次开发，结合了 Ai 的能力，这里小傅哥找到一个做这块功能比较早的，next-ai-draw-io 来演示给大家。感兴趣的伙伴，还可以结合代码做二次开发。

这是一个基于 Next.js 的 Web 应用程序，它将 AI 功能与 draw.io 图表集成在一起。该应用程序允许您通过自然语言命令和 AI 辅助可视化来创建、修改和增强图表。

### 1. 代码下载

代码：[https://github.com/DayuanJiang/next-ai-draw-io](https://github.com/DayuanJiang/next-ai-draw-io)

```java
git clone https://github.com/DayuanJiang/next-ai-draw-io.git
```

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-06.png" width="950px"/>
</div>

下载代码后，注意修改配置文件。

### 2. 启动工程

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-07.png" width="650px"/>
</div>

- 进入 package.json 点击绿色箭头执行启动。

### 3. 访问项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/draw.io-08.png" width="950px"/>
</div>

- 访问 http://localhost:6002 这样你就可以提问来让它绘制图了。这个效果还不错。

---

### Md Road Map Dubbo (`docs/md/road-map/dubbo.md`)

---
title: Dubbo
lock: need
---

# Dubbo 使用教程和原理分析

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=828140981&bvid=BV1Sg4y1c7m4&cid=1190616538&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，为什么要使用Dubbo、怎么使用Dubbo、Dubbo通信的原理是什么。在学习本文后，你可以避开很多关于 Dubbo 使用时的坑，也能更清楚自己的编码是在做什么。

本文涉及的工程：
- xfg-dev-tech-dubbo：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dubbo](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dubbo)
- xfg-dev-tech-dubbo-test：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dubbo-test](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dubbo-test)

## 一、为什么使用

随着互联网场景中所要面对的用户规模和体量的增加，系统也需要做相应的拆分设计和实现。随之而来的，以前的一套系统，现在成了多个微服务。如：电商系统，以前就在一个工程中写就可以了，现在需要拆分出，用户、支付、商品、配送、活动、风控等各个模块。那么这些模块拆分后，如何高效的通信呢？

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-dubbo-01.png?raw=true" width="650px">
</div>

- 关于通信，就引入了 RPC 框架，而 Dubbo 就是其中的一个实现方式。
- 那为啥用 Dubbo 呢？其实核心问题就一个，为了提高通信效率。因为 Dubbo 的底层通信是 Socket 而不是 HTTP 所以通信的性能会更好。同时 Dubbo 又有分布式的高可用设计，在一组部署了交易服务的实例宕机后，会被从注册中心摘除，之后流量会打到其他服务上。

## 二、要怎么使用

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-dubbo-02.png?raw=true" width="650px">
</div>

Dubbo 的使用分为2方，一个是接口的提供方，另外一个是接口的调用方。接口的提供方需要提供出被调用方使用接口的描述性信息。这个信息包括：接口名称、接口入参、接口出参，只有让调用方拿到这些信息以后，它才能依托于这样的接口信息做一个代理操作，并在代理类中使用 Socket 完成双方的信息交互。

所以你看上去调用 RPC 接口好像和使用 HTTP 也没啥区别，无非就是引入了 POM 配置，之后再配置了注解就可以使用了。但其实，它是把你的 Jar 当做代理的必要参数使用了。**本文也会介绍，具体是怎么代理的**

## 三、使用的案例

对于编程的学习来说，其实最开始的那一下，不是搞明白所有原理，而是先让自己可以看到运行出来的效果。哎，之后就去分析原理，这样会舒服的多。

所以小傅哥这里提供了一套简单的 Dubbo 使用案例，只要你满足最基本的配置条件，就可以运行出效果；
1. JDK 1.8
1. Maven 3.x - jdk1.8支持的就可以
2. Dubbo 3.1.4 - POM 中已经配置，与2.x最大的使用上的区别就是一些注解的使用
3. Zookeeper 3.4.x - 如果你只是按照本文中的直连模式测试，那么不安装 Zookeeper 也可以

### 1. 接口提供方

工程案例创建结构，采用的是 DDD 结构。但和 DDD 一点关系没有。如果你对工程创建有疑惑，可以参考 [《Java 简明教程》之 DDD 架构](https://bugstack.cn/md/road-map/ddd.html)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-dubbo-03.png?raw=true" width="750px">
</div>

#### 1.1 接口定义

**源码**：`cn.bugstack.dev.tech.dubbo.api.IUserService`

```java
public interface IUserService {

    Response<UserResDTO> queryUserInfo(UserReqDTO reqDTO);

}
```

- 接口定义平平无奇，但第1个坑暗藏玄机！
- 也就是，所有的 Dubbo 接口，出入参，默认都需要继承 Serializable 接口。也就是 UserReqDTO、UserResDTO、Response 这3个类，都得继承 Serializable 序列化接口。

#### 1.2 接口实现

**源码**：`cn.bugstack.dev.tech.dubbo.trigger.rpc.UserService`

```java
@Slf4j
@DubboService(version = "1.0.0")
public class UserService implements IUserService {

    @Override
    public Response<UserResDTO> queryUserInfo(UserReqDTO reqDTO) {
        log.info("查询用户信息 userId: {} reqStr: {}", reqDTO.getUserId(), JSON.toJSONString(reqDTO));
        try {
            // 1. 模拟查询【你可以从数据库或者Redis缓存获取数据】
            UserResDTO resDTO = UserResDTO.builder()
                    .userId(reqDTO.getUserId())
                    .userName("小傅哥")
                    .userAge(20)
                    .build();

            // 2. 返回结果
            return Response.<UserResDTO>builder()
                    .code(Constants.ResponseCode.SUCCESS.getCode())
                    .info(Constants.ResponseCode.SUCCESS.getInfo())
                    .data(resDTO).build();
        } catch (Exception e) {
            log.error("查询用户信息失败 userId: {} reqStr: {}", reqDTO.getUserId(), JSON.toJSONString(reqDTO), e);
            return Response.<UserResDTO>builder()
                    .code(Constants.ResponseCode.UN_ERROR.getCode())
                    .info(Constants.ResponseCode.UN_ERROR.getInfo())
                    .build();
        }
    }

}
```

- 接口实现平平无奇，但第2个坑暗藏玄机！
- Dubbo 的实现接口，需要被 Dubbo 自己管理。所以 Dubbo 提供了 @DubboService 注解。有些小卡拉米，使用的是不是 Spring 的 @Service 呀？尤其是以前的 Dubbo 版本 `2.7.*` 它的注解也是 @Service 也不留神就用成了 Spring 的 @Service。一个小bug，又调了一上午。

#### 1.3 工程配置

**application.yml**

```java
dubbo:
  application:
    name: xfg-dev-tech-dubbo
    version: 1.0.0
  registry:
    address: zookeeper://127.0.0.1:2181 # N/A - 无zookeeper可配置 N/A 走直连模式测试
  protocol:
    name: dubbo
    port: 20881
  scan:
    base-packages: cn.bugstack.dev.tech.dubbo.api
```

- 配置信息平平无奇，但第3个坑暗藏玄机！
- base-packages 扫描的是哪里配置了 Dubbo 的 API 入口，给它入口就行，它会自己找到实现类。但！你要知道 Java 的 Spring 应用能扫描到，能被 Spring 管理，那么 pom 要**直接或者间接**的引导到定义了 Dubbo 的模块。
- 再有一个问题，Spring 应用开发，讲究约定大于配置。你 Application 应用的包名，应该是可以覆盖到其他包名的。比如 Application 都配置到 `cn.bugstack.dev.tech.dubbo.a.b.c.d.*` 去了，它默认就扫不到 `cn.bugstack.dev.tech.dubbo.api` 了。一个小bug，一下午又过去了。 
- 注意：address：如果配置的是 N/A 就是不走任何注册中心，就是个直连，主要用于本地验证的。如果你配置了 zookeeper://127.0.0.1:2181 就需要先安装一个 zookeeper 另外，即使你配置了注册中心的方式，也可以直连测试。

#### 1.4 应用构建

以上信息都准备了，一群小卡拉米开始掉到第4个坑里了！

你有2个应用，一个Dubbo接口提供方、一个Dubbo接口使用方。那么你在给你另外一个应用使用接口的时候，你在 InelliJ IDEA 的 Maven 中执行 Install 了吗？

Install 是干啥的？它是为了让你使用了同一个本地 Maven 配置的应用，可以引入到对方提供的 Jar 包。你 Install 以后，这个 Jar 包就会进入到本地 Maven 仓库了。如果是公司里开发，会有专门的自己家部署的，私有Maven中心仓库，就可以通过 deploy 把本地 Jar 发布上去，那么公司里的伙伴，也就都可以引用了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-dubbo-04.png?raw=true" width="450px">
</div>

- 你要先点击 root 下的 install 操作，这样就会自动构建了。
- 如果你电脑配置有点低，也会出现一些`气人怪相`，比如就刷不进去，install 了也引用不了。记得要 clean 清空下，也可以直接到 maven 文件夹去清空。

### 2. 接口使用方

有些小卡拉米觉得前面的坑都扫干净了，就完事了。没有接下来还有坑，让你一搞搞一天，半夜也睡不好。

#### 2.1 POM 引入

```xml
<dependency>
    <groupId>cn.bugstack</groupId>
    <artifactId>xfg-dev-tech-dubbo-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
```

- POM 的配置，就是把 Jar 包给引用进来。因为 Dubbo 需要根据这个接口，做一个代理操作。**不引入，你代码就爆红啦！爆红啦！🌶**

#### 2.2 消费配置

**源码**：`application.yml`

```java
dubbo:
  application:
    name: xfg-dev-tech-dubbo
    version: 1.0.0
  registry:
     address: zookeeper://127.0.0.1:2181
#    address: N/A
  protocol:
    name: dubbo
    port: 20881
```

- 配置了 zookeeper 你就用第一个，代码中对应 `@DubboReference(interfaceClass = IUserService.class, version = "1.0.0")`
- 配置了 N/A 你就用第二个，代码中必须指定直连。`@DubboReference(interfaceClass = IUserService.class, url = "dubbo://127.0.0.1:20881", version = "1.0.0")`

#### 2.3 代码配置

**源码**：`cn.bugstack.dev.tech.dubbo.consumer.test.ApiTest`

```java
// 直连模式；@DubboReference(interfaceClass = IUserService.class, url = "dubbo://127.0.0.1:20881", version = "1.0.0")
@DubboReference(interfaceClass = IUserService.class, version = "1.0.0")
private IUserService userService;

@Test
public void test_userService() {
    UserReqDTO reqDTO = UserReqDTO.builder().userId("10001").build();
    Response<UserResDTO> resDTO = userService.queryUserInfo(reqDTO);
    log.info("测试结果 req: {} res: {}", JSON.toJSONString(reqDTO), JSON.toJSONString(resDTO));
}
```

**测试结果**

```java
2023-07-08 15:37:22.291  INFO 62481 --- [           main] c.b.d.tech.dubbo.consumer.test.ApiTest   : 测试结果 req: {"userId":"10001"} res: {"code":"0000","data":{"userAge":20,"userId":"10001","userName":"小傅哥"},"info":"成功"}
2023-07-08 15:37:22.324  INFO 62481 --- [tor-Framework-0] o.a.c.f.imps.CuratorFrameworkImpl        : backgroundOperationsLoop exiting
```

- 如果不出啥意外，到这你就可以直接启动运行了。并看到测试结果。
- 但别忘记了，你启动的时候，需要先启动 xfg-dev-tech-dubbo 让接口提供方跑起来。

## 四、原理的分析

都说 Jar 是提供可描述性信息的，对方才能代理调用。那么这个过程是怎么干的呢，总不能一问这个，就让小卡拉米们去手写 Dubbo 呀！所以小傅哥会通过最简单模型结构，让你了解这个 Dubbo 通信的原理，方便小卡拉米们上手。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-dubbo-06.png?raw=true" width="850px">
</div>

- 如果所示，接口使用方，对接口进行代理。什么是代理呢，代理就是用一个包装的结构，代替原有的操作。在这个包装的结构里，你可以自己扩展出任意的方法。
- 那么，这里的代理。就是根据接口的信息，创建出一个代理对象，在代理对象中，提供 Socket 请求。当调用这个接口的时候，就可以对接口提供方的，发起 Socket 请求了。
- 而 Socket 接收方，也就是接口提供方。他收到信息以后，根据接口的描述性内容，进行一个反射调用。这下就把信息给请求出来，之后再通过 Socket 返回回去就可以了。

好，核心的原理就这么点。接下来，我们从代码中看看。

### 1. 接口反射 - 提供方

**源码**：`cn.bugstack.dev.tech.dubbo.trigger.socket.RpcServerSocket`

```
/* Detailed source-code truncated for AI context efficiency. */
```

这段代码主要提供的功能包括：
1. Netty Socket 启动一个服务端。
2. 注入 ApplicationContext applicationContext 用于在接收到请求接口信息后，获取对应的 Bean 对象。
3. 根据请求来的 Bean 对象，以及参数的必要信息。进行接口的反射调用。
4. 最后一步，就是把接口反射请求的信息，再通过 Socket 返回回去。

### 2. 接口代理 - 调用方

打开工程：[xfg-dev-tech-dubbo-test](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dubbo-test)

**源码**：`cn.bugstack.dev.tech.dubbo.consumer.config.RPCProxyBeanFactory`

```
/* Detailed source-code truncated for AI context efficiency. */
```

这段代码主要提供的功能包括：
1. 实现  `FactoryBean<IUserService>` 为的是把这样一个代理对象，交给 Spring 容器管理。
2. 实现 Runnable 接口，并在接口中，创建 Netty 的 Socket 客户端。客户端中接收来自服务端的消息，并临时存放到缓存中。**注意 Dubbo 中这块的处理会复杂一些，以及请求同步响应通信，这样才能把各个接口的调动记录下来**
3. `getObject()` 对象中，提供代理操作。代理里，就可以自己想咋搞咋搞了。而 Dubbo 也是在代理里，提供了如此的操作，对接口提供方发送请求消息，并在超时时间内返回接口信息。因为反射调用，需要你`提供类`、`方法`、`入参类型`、`入参内容`，所以我们要把这些信息传递给接口提供方。

### 3. 服务测试 - 消费验证

- 启动 xfg-dev-tech-dubbo
- 测试 xfg-dev-tech-dubbo-test

```java
@Resource(name = "rpcProxyBeanFactory")
private IUserService proxyUserService;

@Test
public void test_proxyUserService(){
    UserReqDTO reqDTO = UserReqDTO.builder().userId("10001").build();
    Response<UserResDTO> resDTO = proxyUserService.queryUserInfo(reqDTO);
    log.info("测试结果 req: {} res: {}", JSON.toJSONString(reqDTO), JSON.toJSONString(resDTO));
}
```

**测试结果**

```java
2023-07-08 16:14:51.322  INFO 74498 --- [           main] c.b.d.tech.dubbo.consumer.test.ApiTest   : 测试结果 req: {"userId":"10001"} res: {"code":"0000","data":{"userAge":20,"userId":"10001","userName":"小傅哥"},"info":"成功"}
```

- 这里我们给 IUserService 注入一个自己代理好的对象，之后就可以调用验证了。
- 好啦，到这我们就把关于 Dubbo 的事交代明白了，以上内容较多。小卡拉米需要细细的品味吸收！

---

### Md Road Map Dump Mat (`docs/md/road-map/dump-mat.md`)

---
title: dump eclipse mat
lock: need
---

# Eclipse MAT 分析 Java heap space dump 日志

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

写了这么久Java代码，操作了那么多发布上线，那你看到过`java.lang.OutOfMemoryError: Java heap space`吗？如果有幸看到了，你是怎么解决的呢？是束手无策，还是有排查工具。如果这样的问题是被面试问的，没做过就很难回答了。那么怎么学习一下呢？

<div align="center">
    <img src="https://bugstack.cn/images/article/zsxq/student-learn-01.gif" width="150px">
</div>

**什么场景才会有 OutOfMemoryError**

能写出 OutOfMemoryError 的不是编码不精，就是故意埋坑。其实很多时候我们很难在正常编码写出一个 OutOfMemoryError，因为这个过程你需要大量的往内存加数据，逐步把 JVM 的内存耗尽。而只是1G内存容量（-Xmx1G），仅订单数据就要300多万条记录，谁又能写个 MyBatis SQL 操作，要一次直接把`300万`数据查询到程序内存里呢。

不过，还真可能有！但这个不是程序员故意编码查询300万，而是在做数据导出的时候，处理分页的加法计算有问题，导致每次都是 limit 0,n，n 不断的加大。正确的应该是 limit m,n 这样的查询。这样的 `OutOfMemoryError`，在过往工作中就遇到过，最终经过排查到一次要从数据库获取几百万条数据，导致服务宕机。

那么，为了更好的让大家学习到这样的场景以及使用工具排查，小傅哥这里专门做了案例。可以一起学习下。

## 一、环境准备

为了方便大家进行学习验证，小傅哥这里准备好了一个测试工程和相关的环境安装。你可以在安装完工程后，执行 `ApiTest#test_insert` 向数据库写入250万数据，便于测试。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-01.png" width="450px">
</div>

- 工程：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dump](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-dump)
- 说明：`dev-ops` 下提供了 docker 安装 mysql 以及初始化表。如果你没有 docker 也可以直接本地数据库导入库表。

## 二、软件安装

### 1. 分析软件

对于 OutOfMemoryError 的错误排查，需要让工程导出 dump 日志文件，之后通过软件工具分析。分析 dump 的软件有2个常见的；免费的 Eclipse MAT、付费的 JProfiler(可短期体验)

- Eclipse MAT：[https://eclipse.dev/mat/downloads.php](https://eclipse.dev/mat/downloads.php)
- JProfiler：[https://www.ej-technologies.com/download/jprofiler/files](https://www.ej-technologies.com/download/jprofiler/files) - `学会 MAT 这个可以自己体验`

### 2. Eclipse MAT 安装配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-02.png" width="450px">
</div>

#### 2.1 加大内存

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-04.png" width="550px">
</div>

```java
-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.600.v20231106-1826.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.aarch64_1.2.800.v20231003-1442
-vmargs
--add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
-Xms4096m
-Xmx4096m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread
```

- 需要配置 `-Xms4096m`、`-Xmx4096m` 否则过大的 dump 日志，就不能加载进去分析了。大一点配置分析的更快。

#### 2.2 `does not contain the JNI_CreateJavaVM symbol.` 报错处理

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-03.png" width="450px">
</div>

```java
<array>
            
  <string>-vm</string>
  <string>/Library/Java/JavaVirtualMachines/jdk1.8.0_341.jdk/Contents/Home/bin</string>

  <string>-keyring</string>
  <string>~/.eclipse_keyring</string>
        
</array>
```

- 如果遇到 `The JVM shared library "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/../lib/server/libjvm.dylib" does not contain the JNI_CreateJavaVM symbol.` 可以打开 Info.plist 添加 -vm 和 jdk 路径。

## 三、产生 dump 案例

首先你需要为你要运行的方法添加 VM Options 当你运行一个方法后，添加 JVM 配置，这样才能到处 dump

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-05.png" width="950px">
</div>

- `-Xms128M -Xmx128M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=../xfg-dev-tech-dump/docs/dump`
- HeapDumpPath 为你的工程完成路径，到出到 dump 文件夹下。
- 运行方法后，就可以在 docs/dump 就可以看到产生的日志了。

### 1. 数据库查询

```java
<select id="queryPage" resultMap="dataMap">
        SELECT * FROM user_order
        limit 0, 2500000
</select>

@Test
public void test_java_heap_space_sql() throws InterruptedException {
    while (true){
        userOrderDao.queryPage();
    }
}
```

### 2. 线程池过大

```java
@Test
public void test_thread_pool_java_heap_space() {
    // 创建一个固定大小的线程池
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    try {
        // 不断提交占用大量内存的任务
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            executorService.submit(new MemoryHogTask());
        }
    } catch (OutOfMemoryError e) {
        System.out.println("Caught OutOfMemoryError: " + e.getMessage());
    } finally {
        // 关闭线程池
        executorService.shutdown();
    }
}

static class MemoryHogTask implements Runnable {
    @Override
    public void run() {
        try {
            // 分配一个大数组来占用内存
            int[] memoryHog = new int[1000000]; // 大约占用 4MB 内存
            // 模拟一些计算以避免 JIT 优化掉内存分配
            for (int i = 0; i < memoryHog.length; i++) {
                memoryHog[i] = i;
            }
            // 保持任务在一定时间内占用内存
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
```

### 3. list 添加过多数据

```java
@Test
public void test_java_heap_space_list() throws InterruptedException {
    List<byte[]> list = new ArrayList<>();
    while (true) {
        byte[] bytes = new byte[1024 * 1024 * 1024];
        list.add(bytes);
        TimeUnit.SECONDS.sleep(1);
    }
}
```

- 这类场景是比较多的，比如我们做营销活动，要把很多的活动数据预热到缓存，如果 JVM 配置的比较低，是可能会出现 `Java heap space` 的。

## 四、Eclipse MAT 分析

### 1. 导入 dump 文件

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-06.png" width="650px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-07.png" width="650px">
</div>

### 2. 查看统计树

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-08.png" width="450px">
</div>

### 3. 排序对象

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-09.png" width="850px">
</div>

### 4. 引用关系

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-10.png" width="850px">
</div>

- 点击查看，被谁引用了。

### 5. 逐层分析 - 进入对象详情

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-11.png" width="850px">
</div>

- 看看这个 Object 值装的是什么。

### 6. 发现问题

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-12.png" width="850px">
</div>

- 看到了在检索数据库数据。其实前面就已经定义到哪里的方法导致，这里可以具体看到细节。

### 7. 其他分析

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-dump-13.png" width="650px">
</div>

- 我们本案例采用的是 MySql 8.x 如果你使用其他线程池工具，还可能会返回具体的 SQL 语句一起打印出来。方便分析。

好啦，有了这样一个分析过程，你也可以尝试熟悉下工具，分析分析其他的 Java heap space 场景。几次玩下来也就熟悉这个工具了。

--- 

其他工具；[https://visualvm.github.io/](https://visualvm.github.io/)

---

### Md Road Map Dump Visualvm (`docs/md/road-map/dump-visualvm.md`)

---
title: dump VisualVM
lock: need
---

# VisualVM 分析 Java heap space dump 日志

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

没毕业前以为学编程，以为工作后就只是写代码。工作后才发现，写代码只是一少部分工作。

`JMeter 压测`、`Remote JVM Debug - 远程调试`、`AREX - 流量录制&回放`、`ELK - 分布式日志`、`普罗米修斯监控`、`Arthas`、`Dump日志分析`等，但凡一样不会，基本就会在某一个场景踩坑。**小则是报警异常，大则是线上事故！**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-linux-01.gif" width="150px">
</div>

**👨🏻‍💻程序员，也是高危行业呀！**

从互联网草蜢时代，到现在工作了这么多年，也是见证了很多程序员因为写Bug毕业啦🎓，即使不是被开除，往往重大的事故也会影响未来的绩效、加薪和晋升。这些事故按；照影响时长、影响用户量、造成的资损、解决的时长等，会被定级为 P0、P1、P2、P3 不同级别的事故。

所以，到目前有越来越多的辅助工具，来帮助研发提高代码交付质量，以及各类系统异常分析工具，提高问题排查效率。类似这样的系统、服务、组件，小傅哥已经在 [bugstack.cn 编程路书](https://bugstack.cn/md/road-map/road-map.html) 做了大量的案例讲解。今天小傅哥在给大家分享一个关于 VisualVM 的使用。

## 一、关于 VisualVM

VisualVM 是一款可视化 Java 故障排除工具，集成了 JDK 命令行工具和轻量级性能分析功能。专为开发和生产环境设计。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-01.png" width="750px">
</div>

下载：[https://visualvm.github.io/download.html](https://visualvm.github.io/download.html)

> 接下来，小傅哥会结合 VisualVM 做一些常用的案例，方便伙伴学习。

## 二、案例 - 分析大对象

### 1. 测试工程

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-02.png" width="750px">
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-visualvm](https://github.com/fuzhengwei/xfg-dev-tech-visualvm)
- 说明：这是一个简单的测试工程，通过访问接口产生大对象。之后在通过 JmapDumpController 接口，执行命令，产生 Dump 文件。之后在使用 VisualVM 分析产生的 Dump 日志，定位是哪个对象导致的问题。

### 2. 执行程序

首先，启动 xfg-dev-tech-visualvm 应用程序。之后执行 visualvm-test.sh 脚本，Windows 用户需要在 powershell 里执行，Mac 电脑可以直接在 IntelliJ IDEA 点击绿色箭头执行。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-03.png" width="750px">
</div>

- 首先，点击启动程序，本地运行即可。一般公司里线上的应用，也有专门下载 dump 日志的地方。
- 之后，执行 `./visualvm-test.sh` 这部分写了测试程序的脚本和获取 dump 日志的操作。

#### 2.1 接口；创建对象

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 2.2 接口；获取日志（dump）

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 2.3 脚本；统一执行

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 整个脚本，会帮助我们执行接口请求以及获取 dump 日志。

### 3. Dump 分析

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-05.png" width="750px">
</div>

- 首先，先通过 VisualVM load dump 日志文件，之后点击 Instances By Size 大的文件。
- 之后，对大的文件对象，点击 references 这样就可以看到是哪个对象影响的问题了。很快的就能帮你分析出程序内产生大的对象的问题原因。

## 三、案例；GC 插件

VisualVM 还有类似于[普罗米修斯](https://bugstack.cn/md/road-map/grafana.html)一样的监控，可以查看到 JVM 运行情况。也可以帮助我们分析程序运行情况。

### 1. 安装插件 - VisualVM

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-06.png" width="750px">
</div>

- 在 VisualVM 安装 Visual GC 插件。

### 2. 安装插件 - IntelliJ IDEA

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-07.png" width="750px">
</div>

- 也可以给 Intellij IDEA 安装一个 VisualVM Launcher 插件，启动程序可以直接使用。

### 3. 进入监控

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-09.png" width="750px">
</div>

- 打开 VisualVM 看到本地启动的程序，之后打开 Visual GC
- 这里还可以看见 Monitor、Threads、Profiler，方便我们分析程序

### 4. GC 说明

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-dev-tech-visualvm-08.png" width="750px">
</div>

- 如图，各个模块展示了 JVM 运行状况，从这里可以看到程序占用内存的情况。如果是压测验证，可以打开辅助分析。

---

### Md Road Map Elk (`docs/md/road-map/elk.md`)

---
title: ELK
lock: need
---

# ELK 使用教程采集系统日志 Elasticsearch、Logstash、Kibana

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=664765195&bvid=BV1pa4y1R7Rh&cid=1369260100&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过易于上手实操的方式，教会读者完成系统ELK日志采集的对接和使用。那你知道对于一个系统的上线考察，必备的几样东西是什么吗？其实这也是面试中考察求职者，是否真的做过系统开发和上线的必备问题。包括：[服务治理(熔断/限流)](https://bugstack.cn/md/road-map/ratelimiter.html)、[监控](https://bugstack.cn/md/road-map/grafana.html)和日志，如果你做的系统里没有这样几个东西，一种是说明系统是玩具项目，另外一种就是压根没做过或者没关心过。前面的已经写完了，所以今天来给大家写ELK日志。

本文涉及的工程：

- xfg-dev-tech-elk：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-elk](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-elk)
- 官网：[https://www.elastic.co/cn/](https://www.elastic.co/cn/)

## 一、简要说明

Elastic Stack 技术栈，别是 `Elasticsearch`、`Logstash`、`Kibana` 组成，简称 ELK 是一套针对日志数据做解决方案的框架。它使您能够聚合来自所有系统和应用程序的日志，分析这些日志，并创建可视化来进行应用程序和基础设施监控、更快的故障排除、安全分析等。

- E = Elasticsearch：Elasticsearch 是在 Apache Lucene 上构建的分布式搜索和分析引擎。对各种语言、高性能和无架构 JSON 文档的支持使 Elasticsearch 成为各种日志分析和搜索使用案例的理想选择。 
- L = Logstash：Logstash 是一个开源数据摄取工具，允许您从各种来源收集数据，转换数据，并将数据发送到您希望的目标。通过预构建的筛选器和对 200 多种插件的支持，Logstash 使用户能够轻松摄取数据，无论数据源或类型如何。 
- K = Kibana：Kibana 是一种数据可视化和挖掘工具，可以用于日志和时间序列分析、应用程序监控和运营智能使用案例。它提供了强大且易用的功能，例如直方图、线形图、饼图、热图和内置的地理空间支持。此外，付费的 Kibana 还有 x-pack-jdbc 可以使用，让你就像使用 MyBatis 操作 MySQL 数据库一样操作 Elasticsearch 数据。

综上，3个组件的组合使用。由 Logstash 将摄取、转换数据并将其发送到 Elasticsearch 为摄取的数据编制索引，并且分析和搜索这些数据。最终 Kibana 会将分析结果可视化。也就是你可以在 Kibana 上实时看到系统的运行日志。

## 二、环境配置

这里小傅哥做了个工程案例，并配有对应的环境安装、日志上报，你只需要跟随接下来的文章说明，即可知道 ELK 如何配置和使用。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-01.png?raw=true" width="600px">
</div>

- 环境；jdk 1.8、Maven 3.6.x、Docker 
- 组件；ELK version 7.17.14 支持 ARM&AMD
- 代码；在 xfg-dev-tech-elk 测试工程中提供了测试代码和环境安装，绿色按钮点击即可安装【确保你已经本地安装了 Docker】

### 1. 环境配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-02.png?raw=true" width="600px">
</div>

- docker-compose.yml 运行时会加载下面的 kibana、logstash 配置信息。
- kibana.yml 设置了资源的基本信息，包括 ES 的连接，中文汉化。
- logstash.conf 设置了日志的格式，上报到 es:9200 的地址信息。这些都可以保持默认不用修改。

### 2. 安装环境

```
/* Detailed source-code truncated for AI context efficiency. */
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-03.png?raw=true" width="850px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-04.png?raw=true" width="850px">
</div>

- 这是 docker compose 执行脚本，如果你本地已经安装了 Docker 可以直接执行 安装即可。
- 安装完成后，当你看到如上截图，则表示已经运行。注意 Quick Actions 下可以进入日志和控制台。如果启动失败，可以检查日志。

### 3. 日志配置

#### 3.1 引入POM - logstash

```pom
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.3</version>
</dependency>
```

这个Jar是为了上报应用日志用的。工程的根目录下引入是定义版本，在 xfg-dev-tech-app 模块下引入是具体的引入。

#### 3.2 logback 采集

```yml
# logstash部署的服务器IP
logstash:
  host: 127.0.0.1
```

```xml
<springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="127.0.0.1"/>


<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    
    <destination>${LOG_STASH_HOST}:4560</destination>
    <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

<root level="info">
    <appender-ref ref="LOGSTASH"/>
</root>
```

- LOG_STASH_HOST 通过占位符可以使用 yml 配置，这样方便后期动态调整。

## 四、应用测试

### 1. 启动应用&检测上报

```java
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    /**
     * curl http://localhost:8091/api/ratelimiter/login?fingerprint=uljpplllll01009&uId=1000&token=8790
     */
    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login(String fingerprint, String uId, String token) {
        log.info("模拟登录 login fingerprint:{}", fingerprint);
        return "模拟登录：登录成功 " + uId;
    }

}
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-05.png?raw=true" width="850px">
</div>

- 地址：[http://0.0.0.0:5601/app/dev_tools#/console](http://0.0.0.0:5601/app/dev_tools#/console)
- 命令：`GET _cat/indices` - 通过命令检测日志上报

### 2. 配置日志

地址：[http://0.0.0.0:5601/app/discover](http://0.0.0.0:5601/app/discover)

#### 2.1 创建索引

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-06.png?raw=true" width="850px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-07.png?raw=true" width="850px">
</div>

- 当你的应用启动后，会上报数据。这个时候在点击 Discover 会提示你有可用的数据。
- 如图创建索引即可。

#### 2.2 回到监控

创建索引后，回到 Discover 即可查看监控日志。在这个阶段，你可以访问应用程序接口，查看上报日志信息；[http://localhost:8091/api/ratelimiter/login?fingerprint=uljpplllll01009&uId=1000&token=8790](http://localhost:8091/api/ratelimiter/login?fingerprint=uljpplllll01009&uId=1000&token=8790)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-elk-08.png?raw=true" width="850px">
</div>

- 当你不断的访问接口，就可以看到上报的日志数据信息了。

---

### Md Road Map Fastjson (`docs/md/road-map/fastjson.md`)

---
title: fastjson
lock: need
---

# fastjson 使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

本文的宗旨在于通过简单干净实践的方式教会读者，使用 fastjson 的一些常用操作方法。这些方法也是日常使用 fastjson 时最为常用的方法，如果你在使用中还有一些案例和特性，或者踩坑经验也可以在本文提交PR

本文涉及的工程：

- xfg-dev-tech-fastjson：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-fastjson](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-fastjson)
- Github：[https://github.com/alibaba/fastjson](https://github.com/alibaba/fastjson)

## 一、常用方法

### 1. 序列化和反序列化

```java
String strJson = JSON.toJSONString(UserEntity.builder().build());
UserEntity userEntity = JSON.parseObject(strJson, UserEntity.class);
```

### 2. 配置序列化字段

```java
// 不被序列化
@JSONField(name="amount", serialize=false)
private Double amount;
// 序列化格式
@JSONField(name="createTime", format="dd/MM/yyyy", ordinal = 3)
private Date createTime;

@JsonProperty("top_p")
private Double topP = 1d;
@JsonProperty("max_tokens")
private Integer maxTokens = 2048;
```

- 对象的属性上添加 `@JSONField`、`@JsonProperty` 都可以改变序列化字段的名字。同时还可以扩展是否被序列化和格式化。

### 3. 排除序列化字段

```java
UserEntity userEntity = UserEntity.builder()
        .amount(100D)
        .userName("xfg")
        .password("abc000")
        .createTime(new Date())
        .build();

SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
Collections.addAll(filter.getExcludes(), "password");
log.info(JSON.toJSONString(userEntity, filter));
```

- 因为有些时候不是你能修改被序列化的对象，如你引入了别人的 JAR 之后需要对某个类进行序列化，但因为有些对象不能被序列化或者不要序列化。那么这个时候就可以通过 filter 过滤的方式进行处理。

### 4. json2map 转换

```java
@Test
public void test_map2json() {
    Map<String, Object> map = new HashMap<>();
    map.put("key1", "xfg");
    map.put("key2", 123);
    map.put("key3", false);
    log.info(JSON.toJSONString(map));
}

@Test
public void test_json2map() {
    String jsonString = "{\"key1\":\"xfg\",\"key2\":123,\"key3\":false}";
    Map<String, Object> map = JSON.parseObject(jsonString, Map.class);
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        log.info("{} : {}", entry.getKey(), entry.getValue());
    }
}
```

- 有些时候我们接收的对象就是个 Map 那么你可以使用 fastjson 来对对象进行 map 的转换或者序列化

### 5. toString 处理

```java
@Test
public void testToString2Bean() throws Exception {
    UserEntity userEntity = UserEntity.builder()
            .amount(100D)
            .userName("xfg")
            .password("abc000")
            .createTime(new Date())
            .build();
    log.info(userEntity.toString());
    log.info(JSON.toJSONString(ToString2Bean.toObject(userEntity.toString(), UserEntity.class)));
}

public static <T> T toObject(String str, Class<T> clazz) throws Exception {
    // 创建一个新的对象
    T obj = clazz.getDeclaredConstructor().newInstance();
    // 获取类对象
    Class<?> objClass = obj.getClass();
    // 解析字符串
    String[] fields = str.substring(str.indexOf("{") + 1, str.indexOf("}")).split(", ");
    // 遍历成员变量
    for (String field : fields) {
    // 获取成员变量名和值
    String[] parts = field.split("=");
    // 获取成员变量对象
    Field objField = objClass.getDeclaredField(parts[0].trim());
    // 设置成员变量可以访问
    objField.setAccessible(true);
    // 设置成员变量的值
    objField.set(obj, convertValue(objField.getType(), parts[1].trim()));
    // 设置成员变量不可访问
    objField.setAccessible(false);
    }
    return obj;
}
```

```java
06:03:46.302 [main] INFO cn.bugstack.xfg.dev.tech.test.ApiTest - UserEntity{userName='xfg', password='abc000', amount=100.0, createTime=2023-09-21 20:03:46}
06:03:46.670 [main] INFO cn.bugstack.xfg.dev.tech.test.ApiTest - {"password":"'abc000'","userName":"'xfg'","createTime":"21/09/2023"}

Process finished with exit code 0
```

- 有一些在方法入参的时候需要用日志打印入参信息。大部分时候都是直接用 json 打印对象，但对于一些较大对象就比较耗时。所以阿里的开发手册是建议这个场景使用 toString 操作。
- 但是 toString 操作后的日志不太便于，在本地进行测试验证。因为不好转对象。所以这里我们写个 toString2Bean 对象的方法。

---

### Md Road Map Frp (`docs/md/road-map/frp.md`)

---
title: Frp 内网穿透
lock: need
---

# Frp 内网穿透，用云服务器IP，教你搭一套内网穿透服务！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=113121469400785&bvid=BV1uR4jesE3Z&cid=25830556905&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

作为一个研发人员，我们经常有诉求把本机正在开发阶段的应用，通过本地部署的方式让外部其他人进行访问验证。尤其是一些给远程远程客户演示的时候，也是非常需要这样的服务。但本机并不是公网IP，都是内网的，怎么样外部访问呢？

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-docker-idea-00.png" width="150px"/>
</div>

**FRP 内网穿透是什么？**

内网穿透是一种技术手段，用于访问位于防火墙或路由器后面的本地网络（内网）中的设备或服务。通常情况下，内网中的设备无法直接通过公网（互联网）进行访问，从而实现隐私保护和安全性。内网穿透技术的目标是突破这一限制，使外部用户能够通过互联网访问内网中的服务或设备。

虽然市面也有一些内网穿透的服务，包括； `natapp`、`coplar`、`花生壳`等，如果你不想折腾，也可以直接使用。但折腾一下，往往会省钱！

## 1. 搭建脚本

这里小傅哥使用了 `fatedier/frp` 0.60 版本进行搭建，提供了相关的运行脚本。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-01.png" width="450px"/>
</div>

- 地址：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-frp](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-frp)
- 官网：[https://github.com/fatedier/frp](https://github.com/fatedier/frp)

### 1.1 frps - 服务端

```java
# https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml
[common]
# 监听端口
bind_port = 7000
# 面板端口
dashboard_port = 7500
# 登录面板的账号密码（修改成自己的）
dashboard_user = admin
dashboard_pwd = admin
# token =
```

- token 如果设定了，需要保持客户端和服务端一致。

```java
# 命令执行 docker-compose -f docker-compose.yml up -d
version: '3.9'
services:
  frps:
    image: fatedier/frps:v0.60.0
    hostname: frps
    container_name: frps
    volumes:
      - "./config/frps.toml:/frps.toml"
    command:
      - "-c"
      - "/frps.toml"
    network_mode: "host"
```

- docker compose 按照脚本，走的是 `network_mode: "host"` 不需要额外指定端口。
- 你需要在云服务器开放 7000、7500 以及需要映射出去的端口。比如客户端配置了 8080、9001 也需要在云服务器开放端口，这样才能访问进来。
- 官网配置：[https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml](https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml) - 这里有很全的配置可以参考。

### 1.2 frpc - 客户端

```java
# 服务端地址 https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml
serverAddr = "117.72.37.243"
# 服务端配置的bindPort
serverPort = 7000
# token =

[[proxies]]
# 代理应用名称，根据自己需要进行配置
name = "xfg-dev-tech-01"
# 代理类型 有tcp\udp\stcp\p2p
type = "tcp"
# 客户端代理应用IP
localIP = "127.0.0.1"
# 客户端代理应用端口
localPort = 8080
# 服务端反向代理端口；提供给外部访问
remotePort = 8080

[[proxies]]
# 代理应用名称，根据自己需要进行配置
name = "xfg-dev-tech-02"
# 代理类型 有tcp\udp\stcp\p2p
type = "tcp"
# 客户端代理应用IP
localIP = "127.0.0.1"
# 客户端代理应用端口
localPort = 9001
# 服务端反向代理端口；提供给外部访问
remotePort = 9001
```

- `localPort = 8080` 是本地应用的端口。
- `remotePort = 8080` 是远程服务器要暴漏出去的端口，这个端口你可以按需调整。

```java
# 命令执行 docker-compose -f docker-compose.yml up -d
version: '3.9'
services:
  frpc:
    image: fatedier/frpc:v0.60.0
    hostname: frpc
    container_name: frpc
    volumes:
      - "./config/frpc.toml:/frpc.toml"
    command:
      - "-c"
      - "/frpc.toml"
    network_mode: "host"
```

- docker compose 安装，同样需要指定 `network_mode: "host"`

## 2. 执行安装

搭建FRP内网穿透需要一台云服务器，其实主要用的就是它的公网IP。不过现在的云服务器都非常便宜，36元就可以购买1年，还能抽取京豆。折算下来也就26元1年了！

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-02.png" width="250px"/>
</div>

- 专属价：[http://618.gaga.plus/](http://618.gaga.plus/)
- 云服务器使用：[https://bugstack.cn/md/road-map/docker.html](https://bugstack.cn/md/road-map/docker.html) - 已录制了相关 Docker、Portainer 环境安装，你可以直接对照操作。

### 2.1 frps - 云服务器安装

#### 2.1.1 上传文件

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-03.png" width="750px"/>
</div>


#### 2.1.2 执行脚本

```java
[root@lavm-aqhgp9nber frps]# docker-compose -f docker-compose.yml up -d
[+] Running 1/1
 ✔ Container frps  Started   
```

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-04.png" width="750px"/>
</div>

你可以进入📃查看启动日志；


```java
WARNING: ini format is deprecated and the support will be removed in the future, please use yaml/json/toml format instead!
2024-09-08 09:51:50.581 [I] [frps/root.go:105] frps uses config file: /frps.toml
2024-09-08 09:51:50.674 [I] [server/service.go:237] frps tcp listen on 0.0.0.0:7000
2024-09-08 09:51:50.674 [I] [frps/root.go:114] frps started successfully
2024-09-08 09:51:50.674 [I] [server/service.go:351] dashboard listen on 0.0.0.0:7500
2024-09-08 09:51:52.429 [I] [server/service.go:576] [cd9f610f66475f3a] client login info: ip [223.72.84.77:10816] version [0.60.0] hostname [] os [linux] arch [amd64]
2024-09-08 09:51:52.447 [I] [proxy/tcp.go:82] [cd9f610f66475f3a] [xfg-dev-tech-02] tcp proxy listen port [9001]
2024-09-08 09:51:52.448 [I] [server/control.go:399] [cd9f610f66475f3a] new proxy [xfg-dev-tech-02] type [tcp] success
2024-09-08 09:51:52.448 [I] [proxy/tcp.go:82] [cd9f610f66475f3a] [xfg-dev-tech-01] tcp proxy listen port [8080]
2024-09-08 09:51:52.448 [I] [server/control.go:399] [cd9f610f66475f3a] new proxy [xfg-dev-tech-01] type [tcp] success
```

#### 2.1.3 开放端口

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-05.png" width="750px"/>
</div>

- 进入云服务器防火墙，开放访问端口。

### 2.2 frpc - 本地安装客户端

#### 2.2.1 执行脚本

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-06.png" width="650px"/>
</div>

- 注意 frpc.toml 是配置服务器的ip和本机应用的ip信息。你需要修改 serverAddr 的 IP 地址，为你的服务器公网 IP 地址。
- 如果你的 IntelliJ IDEA 带有绿色箭头，且本机也安装了 Docker 那么可以直接安装 frpc 客户端。

#### 2.2.2 客户端日志

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-07.png" width="650px"/>
</div>

```java
2024-09-08 10:00:16.472 [I] [sub/root.go:142] start frpc service for config file [/frpc.toml]
2024-09-08 10:00:16.473 [I] [client/service.go:295] try to connect to server...
2024-09-08 10:00:16.533 [I] [client/service.go:287] [adab2679b41d410f] login to server success, get run id [adab2679b41d410f]
2024-09-08 10:00:16.534 [I] [proxy/proxy_manager.go:173] [adab2679b41d410f] proxy added: [xfg-dev-tech-01 xfg-dev-tech-02]
2024-09-08 10:00:16.550 [I] [client/control.go:168] [adab2679b41d410f] [xfg-dev-tech-01] start proxy success
2024-09-08 10:00:16.550 [I] [client/control.go:168] [adab2679b41d410f] [xfg-dev-tech-02] start proxy success
```

#### 2.2.3 服务端日志

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-04.png" width="850px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-08.png" width="850px"/>
</div>

- 客户端启动后，你可以进入到服务端 frps 查看日志，这个时候会注册进来客户端信息。

**你还可以进入 frp 管理后台查看**

地址：[http://117.72.37.243:7500/static/#/](http://117.72.37.243:7500/static/#/) - 修改为你的服务器ip进行访问。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-09.png" width="950px"/>
</div>

- 这里也可以看到你注册上来的各项信息。

## 3. 测试验证

### 3.1 部署应用

在工程中提供了 xfg-dev-tech-app 的应用，你可以本地执行 docker 脚本进行镜像构建和部署。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-10.png" width="950px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-11.png" width="950px"/>
</div>

- 如图，执行1、2、3步骤，打包、构建和部署应用。

### 3.2 访问验证

#### 3.2.1 本地访问

地址：[http://127.0.0.1:8080/api/test](http://127.0.0.1:8080/api/test)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-12.png" width="550px"/>
</div>

#### 3.2.2 穿透访问

地址：[http://117.72.37.243:8080/api/test](http://117.72.37.243:8080/api/test)

## 4. 同类产品

- [EasyTier 一个简单、安全、去中心化的内网穿透 VPN 组网方案](https://www.easytier.top/)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-frp-13.png" width="550px"/>
</div>

---

### Md Road Map Git (`docs/md/road-map/git.md`)

---
title: Git
lock: need
---

# Git 使用说明和配置

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=113087713643443&bvid=BV1idHUeLECY&cid=25755911382&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

**不会Git操作的伙伴，轻则写不了代码，重则误操作搞丢自己的代码或者干掉别人的代码。** 因为进入公司后，就不只是你一个人在一个工程上写代码，而是所有这个项目组的伙伴都需要在这个工程上写代码，大家要在统一的Git的规范完成代码开发和提交。—— 🤨 不信的话，进入公司乱删个Git分支或者随便任何一个分支提交代码试试。

<div align="center">
    <img src="https://bugstack.cn/images/article/project/big-market/big-market-v7-01.gif" width="150px">
</div>

**Git的作用是什么？**

你可以想象下，当你有10个小伙伴都需要在一个 txt 文档里，写一份老师👩🏻‍🏫上课的笔记📒，把信息进行汇总、互相完善、用于课后学习。那么怎么保证大家做的课堂内容都能顺利的写在一份 txt 呢，而且不要互相删除，也不要丢失谁的信息呢？

这个就是 Git 的用途。Git 是一种分布式版本控制系统，用于高效地管理和跟踪源代码和文件的历史记录，支持多人协作开发及分支管理，提供可靠的版本回退和合并机制，从而提高开发效率和代码质量。

## 1. Git 起源故事

讲到 Git 就不得不提一下 Linux，因为如果没有 Linux 也就没有 Git 的诞生，这里是有一段 **10天** 写出 Git 的故事！

众所周知，Linus 于 1991年 创建了开源的 Linux，从此 Linux 系统不断发展壮大。但 Linux 的壮大是靠全世界热心的开发者参与的，不过这么多人在世界各地为 Linux 编写代码，那代码是如何管理的呢？事实是，2002 之前，合并代码的操作都是 Linux 老爷子自己手动合并的！

但 2000 年的时候，不是已经 [SVN](https://zh.wikipedia.org/wiki/Subversion) 可以使用了吗？但 Linus 坚决反对 CVS、SVN 这些集中式的管理工具，不仅速度差还得联网操作。虽然有商用版的功能好一些，但这与 Linux 开源精神不符。所以 Linus 就不用，看人家这开源精神！

不过到了 2002年，Linux 都发展10年了，在这么手动的合并代码，让社区的兄弟也苦不堪言，强烈反对。为此，林纳斯·托瓦兹（Linus Torvalds）决定使用 BitKeeper 作为 Linux 内核主要的版本控制系统用以维护代码。BitKeeper 的东家 BitMover 公司，看 Linux 开源的不容易，授权 Linux 社区免费使用这个版本控制系统。

哈哈哈，但好景不长！2005年，安德鲁·垂鸠（Andrew Tridgell）写了一个简单程序，可以连接 BitKeeper 的仓库，BitKeeper 著作权拥有者拉里·麦沃伊认为安德鲁·垂鸠对 BitKeeper 内部使用的协议进行逆向工程，决定收回无偿使用 BitKeeper 的许可。Linux 内核开发团队与 BitMover 公司进行磋商，但无法解决他们之间的歧见。林纳斯·托瓦兹决定自行开发版本控制系统替代 BitKeeper ，以10天的时间编写出 git 第一个版本！—— 牛皮！

有了 Git 以后，GitHub 平台也于2007年10月1日开始开发。网站于2008年2月以beta版本开始上线，4月份正式上线。GitHub 里面的项目可以通过标准的 Git 命令进行访问和操作。—— 这就是 Linux、Git、Github 的故事。

## 2. 软件安装

Git 是一个软件工具，在使用前需要进行安装。

- 地址：[https://git-scm.com/downloads](https://git-scm.com/downloads) - `选择需要的版本下载` 网盘资源：[https://www.alipan.com/s/LqwsNfHRx54](https://www.alipan.com/s/LqwsNfHRx54) - `也提供了 Git 软件，在 dev-ops -> 环境 -> git 下`
- 演示：[https://learngitbranching.js.org/](https://learngitbranching.js.org/) - `可直接查看动画效果，引导式学习Git命令操作。`

**配置代理**

```java
git config --global http.proxy ip:port
git config --global https.proxy ip:port
```

- 如果你有代理地址可以配置

### 2.1 Mac

```java
# 如果你没有 brew 命令，则需要先安装下；https://brew.sh/index_zh-cn
brew install git
```

### 2.2 Windows

- [32-bit Git for Windows Setup](https://github.com/git-for-windows/git/releases/download/v2.41.0.windows.1/Git-2.41.0-32-bit.exe)
- [64-bit Git for Windows Setup](https://github.com/git-for-windows/git/releases/download/v2.41.0.windows.1/Git-2.41.0-64-bit.exe)

### 2.3 Linux

#### Debian/Ubuntu

获取适用于您的 Debian/Ubuntu 版本的最新稳定版本

**如果没有安装npm可以安装**

```
# sudo apt update
# sudo apt install nodejs npm
# node -v
# npm -v
```

**安装git**

```
# apt-get install git
```

对于 Ubuntu，此 PPA 提供最新的稳定上游 Git 版本

```
# add-apt-repository ppa:git-core/ppa
# apt update; apt install git
```

#### Centos 

```java
sudo yum install git
```

## 3. 配置账户

当你拿到一个Git的仓库（Github、Gitcode、Gitee、GitLab），让你克隆（git clone）代码的时候，不要`虾呵呵`的上去就点个zip下载。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-01.png" width="700px">
</div>

- zip 下载的代码，只是当前分支的，下载后用 IntelliJ IDEA 打开也没有 Git 标识，不能进行仓库的pull、push、checkout等操作。
- 另外对于一些工程内容比较大的项目，直接 zip 下载还可能会失败。

>你要做都是配置账户 ssh 秘钥，或者下载的时候输入 git 仓库账号密码（目前很多仓库为了安全，不在支持账号密码方式下载代码了。）

**注意**：gitcode.com、github.com 都需要创建访问令牌当做账号密码的密码使用。而不是直接使用账号里你设置的那个密码。

如 [https://gitcode.com/setting/token-classic](https://gitcode.com/setting/token-classic)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-20.png" width="850px">
</div>

### 1. 配置git账户

```java
[root@lavm-aqhgp9nber ~]# git config --global user.name "fuzhengwei"
[root@lavm-aqhgp9nber ~]# git config --global user.email "184172133@qq.com"
```

- 用户名和邮箱，更换为你的代码库注册使用的名称和邮箱📮。

### 2. 创建ssh秘钥

```java
[root@lavm-aqhgp9nber ~]# ssh-keygen -t rsa -C "184172133@qq.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:lgf+3a1srOvDD0znv+/jiR3iwMaZtxW94k9FI1HzJAk 184172133@qq.com
The key's randomart image is:
+---[RSA 2048]----+
|            Eoo+.|
|              ooo|
|        .    . .o|
|       . o    ..o|
|        S . . ..o|
|       . oo+o+ .+|
|          .O+=o=.|
|          . Bo@+o|
|           .+@*BB|
+----[SHA256]-----+
```

- 命令：`ssh-keygen -t rsa -C "184172133@qq.com"`
- 操作：一路敲回车同意就可以了。

### 3. 获取ssh秘钥

```java
[root@lavm-aqhgp9nber ~]# cat /root/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7eYQiDe46Jq5CJ6vXtIiM0hxUKKgCoSFIkSQucsZoLjhW53guxmZ0aR+gUZb/M8Xgrk9WMxc32KqQasFy0xPo86Hxagd40fPz+XdwOyokEJC5He6F1********CkATF2YgEdtcRW2RPICjtLr*******DWkS8ez 184172133@qq.com
```

- 命令：`ssh-keygen -t rsa -C "184172133@qq.com"`
- 操作：`Your public key has been saved in /root/.ssh/id_rsa.pub.` 按照提示地址，获取 pub 公钥。如果是linux就通过 cat 获取。如果是本机电脑就按照路径打开。如，我的地址（你要更换为你的）：`cat /Users/fuzhengwei/.ssh/id_rsa.pub`
- 注意：`.ssh` 点开头的文件夹是隐藏文件，Windows/Mac 都可以设置查看隐藏文件。Windows 是设置里配置，Mac 是通过 `Shift + Command + .` 开启和关闭查看隐藏文件。

### 4. 配置ssh秘钥

#### 4.1 gitcode.net

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-02.png" width="600px">
</div>

- 秘钥配置地址：[https://gitcode.net/-/profile/keys](https://gitcode.net/-/profile/keys)

#### 4.2 github.com

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-03.png" width="600px">
</div>

- 秘钥配置地址：[https://github.com/settings/keys](https://github.com/settings/keys)

---

其他的各个代码库平台也都类似，找到配置 ssh 秘钥的地方，把 id_rsa.pub 内容填充进去即可。

## 4. 检出代码 - 命令

通过在公司工作，大家会说检出代码，不会说下载。因为检出对应的是 git clone 命令，而下载是 http 直接点击链接。在我们使用一些图形化的 git 界面操作代码检出的时候，走的也是 git clone 命令。

### 4.1 检出地址

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-04.png" width="600px">
</div>

- 地址：选择工程的 ssh 地址，这个是你配置 ssh 秘钥后的检出方式。

### 4.2 检出命令

#### 4.2.1 默认检出（master）

```java
git clone git@github.com:fuzhengwei/openai-code-review.git
```

- 你可以复制你需要的工程地址进行检出。

#### 4.2.2 指定分支

```java
git clone -b 240720-xfg-init-project git@github.com:fuzhengwei/openai-code-review.git
```

- 添加 `-b 分支名`，可以指定分支名称检出。

#### 4.2.3 其他命令

- git branch：查看当前工程分支
- git branch -r：查看远程分支列表
- git pull：拉取分支最新代码
- git push：推送本地变更的代码。【这样的操作有图形化界面，更方便】
- git fetch：获取远程仓库最新分支变动，这个很有用。在你想操作分支创建新或者看其他人的分支时候，先操作下 git fetch 看下最新的分支变动。
- git merge origin/master：将远程分支的 master 代码合并到本地分支 master 上。【类似这样的操作有图形化界面，点击即可】

## 5. 检出代码 - IntelliJ IDEA

IntelliJ IDEA 本身就提供了 Git 的图形化操作，也是最简单最常用的方式。只要你的代码是通过 Git 检出的，那么通过配置 Git 的 IntelliJ IDEA 打开工程，就会自动的被 Git 管理。

### 5.1 配置 Git

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-05.png" width="700px">
</div>

- 像是 Mac 电脑会自动默认的配置好 IntelliJ IDEA Git 直接使用即可，如果你的电脑在 IntelliJ IDEA 打开工程后，提示没有 Git 则可进入设置手动配置。
- 配置后，点击 Test 可以测试出 Git 的版本。

### 5.2 检出代码

#### 5.2.1 方式1；打开工程前

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-06.png" width="700px">
</div>

#### 5.2.2 方式2；打开工程后

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-07.png" width="400px">
</div>

- 打开工程后，也可以通过菜单栏中的 Git 进行检出操作。

### 5.3 图形界面

#### 5.3.1 分支使用

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-08.png" width="750px">
</div>

#### 5.3.2 提交代码

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-09.png" width="600px">
</div>

#### 5.3.3 查看记录

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-10.png" width="750px">
</div>

#### 5.3.4 查看对比

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-11.png" width="750px">
</div>

- 这个代码对比非常适合代码评审，也可以用于自己学习代码。可以知道任意两个分支的代码差异，也就知道了代码上一次是什么样，这一次是做了什么开发。

#### 5.3.5 合并分支

在公司中很多时候是大家一起在一个工程开发代码，那么这个时候就会涉及合并代码的。如果有多人共同开发一个接口方法，就会在合并的时候产生冲突。所以要特别注意。

注意，📢在Git中，`merge`和`rebase`是两种用于合并分支变更的方法。每种方法都有其特定的用途和行为：

Merge

- **概念**: `merge`命令用于将一个分支的更改合并到当前分支，通常会生成一次新的合并提交（commit），从而保留分支历史。
- **历史记录**: 使用`merge`会保留所有开发历史记录，包括分支点，这使得历史记录图呈现出一个分叉和合并的树状结构。
- **使用场景**: 
  - 当你想保留完整的历史记录，了解如何以及何时进行了分支。
  - 通常用于将分支合并到主分支(如`main`或`master`)时，以保留分支的历史上下文。
- **命令**: 
  ```bash
  git checkout main
  git merge feature-branch
  ```

Rebase

- **概念**: `rebase`命令用于重新定位一系列的提交，可以将分支上的更改申请到另一分支的顶端，因而能得到更线性的历史。
- **历史记录**: Rebase重新写了提交历史（改变了提交的父提交），这会导致更线性的提交历史，从而更清晰，但会丢失分支合并信息。
- **使用场景**:
  - 当你希望提交历史更加简洁和线性。
  - 合并特性分支到主分支前用以避免杂乱的分支合并历史。
  - 需要小心在共享分支上使用，因为重写的提交历史会影响他人。
- **命令**:
  ```bash
  git checkout feature-branch
  git rebase main
  ```

选择何时使用

- **Merge**适合用于保持完整的提交历史，不改变现有提交的哈希。
- **Rebase**适合用于清理提交历史，通常在提交尚未推送至共享存储库时使用。

一般情况下，对于已对外分享的分支，尤其是共享存储库中的`main`或`master`分支，尽量避免使用`rebase`。而对于个人开发的特性分支，`rebase`可以帮助维护一个清晰的提交历史。

**普通合并**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-12.png" width="750px">
</div>

- 在实际的开发中，大家承接新的需求，会从master拉一个新的分支。拉取后，开始编写代码，完成开发后提交。
- 之后切换到master分支，通过把自己的开发的分支合并回master分支进行提交。
- 注意：如果多人开发，同时修改一个类，可能会引起合并冲突，这个审核要点开类，查看冲突进行合并，不要把自己和他人的代码合并丢失。

**冲突合并**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-22.png" width="950px">
</div>

1. 选择，你要从哪个分支合并到 test 分支。右键选择 Merge into test
2. 如果你合并到test分支的代码，有其他人也在同一行做了改变或者格式化了代码，就会弹出一个合并冲突。这个时候你需要点 Merge 进行合并。
3. 在点击 Merge 后，你会看到具体冲突的代码是什么，你可以有选择的从左右合并到中，最后点击 Apply。这个时候要注意不要把让别人的代码合并丢喽。
4. 合并完的代码，不要直接 push，你要先本地 install 看是否可以打包。以及如果可以运行的话，可以本地先跑一下。 最后 push 提交合并代码即可。

#### 5.3.6 回滚分支

回滚提交和回滚push

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-13.png" width="750px">
</div>

如果出现了合并代码冲突后，丢失了代码，那么这个时候一般要进行回滚操作，重新合并。

虽然 Git 提供了回滚代码的功能，但一定要谨慎使用。怎么谨慎？第一个谨慎就是 push 的代码一定确保可以构建和运行，否则不要 push！第二个谨慎是要回滚代码，需要和团队中对应的伙伴打招呼，避免影响别人测试或者上线。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-23.png" width="950px">
</div>

1. 先选择要在哪个分支的哪次提交上进行回滚。这里选择的是 test 分支上的提交进行回滚。
2. 这里选择 Hard 回滚。因为我们所有的都是合并到 test 分支，所以 test 分支丢失也没问题。可以重新合并。但要和同组伙伴提前说明。
3. 回滚后，你会看到代码只剩下从回滚往下的提交内容了。
4. 回滚后，你不能直接 push 提交了，这个之后会报错；`fast-forward` 因为此时本地分支落后于远程分支。
5. 所以要通过 `git push origin HEAD --force` 进行强制提交。或者你可以把 test 的远程分支删掉，之后在提交。

## 6. 提交工程 - IntelliJ IDEA

那么首次创建的工程怎么提交到代码库呢？🤔

### 6.1 创建本地仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-14.png" width="550px">
</div>

- Create Git repository 创建一个本地的暂存库。你可以把开发的内容暂时提交到本地仓库中。

### 6.3 提交本地代码

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-15.png" width="550px">
</div>

- 把本地仓库提交到本地代码库待提交列表中。
- 后续你在创建的代码，会默认自动加入进来。*如果你是通过打开文件夹复制进去的，不会被添加，需要手动 +Add*
- 添加后就可以参考 5.3 中的操作提交代码了。

### 6.4 创建远程仓库

你可以选择 GitHub/GitCode/Gitee/GitLab 任意地方创建自己的工程库。教程；
- [https://bugstack.cn/md/road-map/github.html](https://bugstack.cn/md/road-map/github.html)
- [https://bugstack.cn/md/road-map/gitcode.html](https://bugstack.cn/md/road-map/gitcode.html)
- [https://bugstack.cn/md/road-map/gitee.html](https://bugstack.cn/md/road-map/gitee.html)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-16.png" width="650px">
</div>

### 6.5 推送本地工程

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-17.png" width="650px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-18.png" width="650px">
</div>

- 最后推送完成就可以看到自己的代码进入仓库中了！

## 7. 操作界面 - git-gui

Git 附带了用于提交 ( [git-gui](https://git-scm.com/docs/git-gui) ) 和浏览 ( [gitk](https://git-scm.com/docs/gitk) ) 的内置 GUI 工具，但也有一些第三方工具可供用户寻求特定于平台的体验。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230705-01.png?raw=true" width="750px">
</div>

- Git 提供了操作的客户端界面，你可以按需下载使用。
- 地址：[https://git-scm.com/docs/git-gui](https://git-scm.com/docs/git-gui)

## 8. 分支命名

不同公司中对Git的使用分支命名规范也略有差异，不过整体都会分为；`上线`、`预发`、`开发`、`测试`，这样几个分支。如图是一种比较简单使用的拉取分支方式。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-24.png" width="850px">
</div>

- master/main 作为主分支，不可直接修改代码代码，只能从分支合并到主分支进行进行提交。同时，master 分支的合并需要进行审批，审批后才能合并。
- 开发前，先从 master 分支，拉一个开发分支。`2024/10/11/xfg-xxx` 使用带有斜线的分支命名会自动创建文件夹，对于多人开发的项目，可以直接归档。
- 后开发，也就是研发已经完成了本地的验证。进行测试时，可以把研发的开发分支合并到 test 分支，提交、部署、测试。遇到测试bug，需要回到可发分支修改代码，之后合并到 test 分支部署验证。
- pre/release 预发分支，用于测试完成后，把研发的开发分支合并到预发分支进行预发上线，上线后测试人员进行验证。最终完成验证后，把开发分支合并到 master 分支，并需要由架构师对合并代码审批通过。最后进行上线开量验证。
- 如果是修复bug的，可以添加一个 `fix-用户名缩写-具体功能`

## 9. 提交规范

保持一个标准的统一的规范提交代码，在后续的评审、检查、合并，都会非常容易处理。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-git-21.png" width="450px">
</div>

**提交规范**：`type:【需求名】desc #id` 如：`feat:【抽奖算法】O1、Ologn 时间复杂度算法实现 #需求id（github pr/行云等会有自动关联）` *参考Commit message 规范*

```java
# 主要type
feat:     增加新功能
fix:      修复bug

# 特殊type
docs:     只改动了文档相关的内容
style:    不影响代码含义的改动，例如去掉空格、改变缩进、增删分号
build:    构造工具的或者外部依赖的改动，例如webpack，npm
refactor: 代码重构时使用
revert:   执行git revert打印的message

# 暂不使用type
test:     添加测试或者修改现有测试
perf:     提高性能的改动
ci:       与CI（持续集成服务）有关的改动
chore:    不修改src或者test的其余修改，例如构建过程或辅助工具的变动
```

> 前提通知，谨慎回滚。如果是回滚 Master 更要特别小心，别把工作回滚丢了。

## 10. 操作手册

- 文档：[https://git-scm.com/book/zh/v2](https://git-scm.com/book/zh/v2) - `可以直接对照着操作，练习命令`
- PDF：[https://github.com/progit/progit2-zh/releases/download/2.1.62/progit.pdf](https://github.com/progit/progit2-zh/releases/download/2.1.62/progit.pdf)
- 演示：[https://learngitbranching.js.org/](https://learngitbranching.js.org/) - `可直接查看动画效果，引导式学习Git命令操作。`

---

<div align="center">
</div>

- 中文PDF，直接深度学习Git操作！下载：**微信公众号「bugstack虫洞栈」回复「gitbook」**

---

### Md Road Map Gitcode (`docs/md/road-map/gitcode.md`)

---
title: Gitcode
lock: need
---

# Gitcode 使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、前言

Gitcode 也是一个非常优秀的代码仓库管理工具，同时还他有很多其他功能。他是 CSDN 平台提供的仓库管理工具。也是非常不错的仓库。

- 仓库配置 SSH 参考：[https://bugstack.cn/md/road-map/git.html](https://bugstack.cn/md/road-map/git.html)

## 一、账号注册

- 官网：[https://gitcode.net](https://gitcode.net)
- 注册：[https://gitee.com/signup?redirect_to_url=%2F](https://gitee.com/signup?redirect_to_url=%2F)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-01.png?raw=true" width="750px">
</div>

- 它的注册方式直接使用会跳转到 CSDN 直接使用即可。
- 注册后你就会有一个自己的 Gitee，如：[https://gitcode.com/fuzhengwei](https://gitcode.com/fuzhengwei)

## 二、仓库创建

### 1. 创建类型

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-02.png?raw=true" width="550px">
</div>

- 创建仓库，操作步骤与 Github 基本一致。
- 在新建项目的时候，同样也可以从其他仓库导入项目。

### 2. 创建操作

#### 2.1 创建项目

**创建选项**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-03.png?raw=true" width="450px">
</div>

- 项目名称；也就是你最后的项目名称
- URL&标识：选择把项目创建到你的那个组织下，以及路径。一般路径和仓库名称最好保持一致。
- 项目介绍：描述这个项目的。
- 创建类型：你可以选择私有和公开。

**创建完成**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-04.png?raw=true" width="550px">
</div>

- 示例：[https://gitcode.net/fuzhengwei/xfg-frame-ddd](https://gitcode.net/fuzhengwei/xfg-frame-ddd)

#### 2.2 创建组织

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-05.png?raw=true" width="450px">
</div>

- 组织相当于是一个额外的空间，而你是这个组织的管理者。它必须全局唯一。
- 之后你可以在创建项目的时候，选择到组织空间，这样项目就会创建到组织里了。
## 三、代码提交

代码提交到仓库，核心在于把本地代码和远程仓库关联起来。如果你是直接从远程仓库地址，检出到本地的，那么就不需要再次关联了。本场景适用于，你本地有代码库，需要首次提交到远程仓库中。

### 1. 创建本地仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-06.png?raw=true" width="750px">
</div>

- 首先你需要打开 IntelliJ IDEA 工程，选择 VCS 创建一个本地仓库的Git仓库。Create Git Repository

### 2. 关联远程仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-07.png?raw=true" width="750px">
</div>

- 打开你的 Gitee 仓库对应的项目，复制项目 HTTPS 地址，粘贴到 IntelliJ IDEA 项目的远程仓库配置中，点击 OK 即可。
- Manage Remotes 可以设置多个仓库，在push代码的时候，选择对应的地址提交即可。

### 3. 项目代码提交

#### 3.1 添加

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-08.png?raw=true" width="750px">
</div>

- 在工程上右键，把你需要提交的文件，选择 +Add 注意不要把一些不需要提交的文件，也提交上去。
- 你可以先创建一个 `Add to .gitignore` 它可以屏蔽掉一些不要的文件。—— 在 Github 创建工程的时候也有此文件。你也可以先更新 pull 拉取下来。

#### 3.2 提交

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-09.png?raw=true" width="750px">
</div>

- 提交代码快捷键：`Ctrl + K` - 提交到本地仓库

#### 3.3 推送

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230708-10.png?raw=true" width="750px">
</div>

- 推送代码快捷辑：`Ctrl + Shift + K` —— 提交到远程仓库

## 四、提交规范

**分支命名**：`日期_姓名首字母缩写_功能单词`，如：`230708_xfg_buildFramework`

**提交规范**：`作者，type: desc` 如：`小傅哥，fix：修复查询用户信息逻辑问题` *参考Commit message 规范*

```
# 主要type
feat:     增加新功能
fix:      修复bug

# 特殊type
docs:     只改动了文档相关的内容
style:    不影响代码含义的改动，例如去掉空格、改变缩进、增删分号
build:    构造工具的或者外部依赖的改动，例如webpack，npm
refactor: 代码重构时使用
revert:   执行git revert打印的message

# 暂不使用type
test:     添加测试或者修改现有测试
perf:     提高性能的改动
ci:       与CI（持续集成服务）有关的改动
chore:    不修改src或者test的其余修改，例如构建过程或辅助工具的变动
```

---

**此外**，Github 是一个大宝藏，你可以通过检索，找到特别多的优质项目、代码、设计。如：[https://gitcode.net/fuzhengwei](https://gitcode.net/fuzhengwei)

---

### Md Road Map Gitee (`docs/md/road-map/gitee.md`)

---
title: Gitee
lock: need
---

# Gitee 使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

## 一、前言

Gitee 是国内的 Github，也是一个非常优秀的代码仓库管理工具，同时还他有很多其他功能。比如；项目协同、代码扫描、持续集成、测试管理、多云部署以及能效相关的功能。这些功能其实更适合一些中小厂的企业来使用，可以减少自身的建设成本。

- 仓库配置 SSH 参考：[https://bugstack.cn/md/road-map/git.html](https://bugstack.cn/md/road-map/git.html)

## 一、账号注册

- 官网：[https://gitee.com/](https://gitee.com/)
- 注册：[https://gitee.com/signup?redirect_to_url=%2F](https://gitee.com/signup?redirect_to_url=%2F)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-01.png?raw=true" width="450px">
</div>

- 你可以按照Gitee的注册提示，一步一步的填写信息就可以完成账号注册了。
- 注册后你就会有一个自己的 Gitee，如：[https://gitee.com/fustack](https://gitee.com/fustack)

## 二、仓库创建

### 1. 创建类型

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-02.png?raw=true" width="550px">
</div>

- 创建仓库，操作步骤与 Github 基本一致。
- 从 Github/GitLab 导入仓库，这个功能非常好用。如果你拿到了一个 Github 的地址，但访问不了。这个时候你可以通过这个功能，把项目导入到 Gitee 就可以访问了。

### 2. 创建操作

#### 2.1 创建项目

**创建选项**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-03.png?raw=true" width="550px">
</div>

- 仓库名称；也就是你最后的项目名称
- 归属&路径：选择把项目创建到你的那个组织下，以及路径。一般路径和仓库名称最好保持一致。
- 仓库介绍：描述这个项目的。
- 创建类型：默认情况下你只能创建一个私有项目，在审核后，在修改为公开。
- 其他设置；你可以选择一些默认的信息初始化仓库，如；gitignore、开源许可协议、模板、分支等。

**创建完成**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-04.png?raw=true" width="550px">
</div>

- 示例：[https://gitee.com/fustack/xfg-frame-ddd](https://gitee.com/fustack/xfg-frame-ddd)

#### 2.2 创建组织

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-05.png?raw=true" width="750px">
</div>

- 组织相当于是一个额外的空间，而你是这个组织的管理者。它必须全局唯一。
- 之后你可以在创建项目的时候，选择到组织空间，这样项目就会创建到组织里了。

## 三、代码提交

代码提交到仓库，核心在于把本地代码和远程仓库关联起来。如果你是直接从远程仓库地址，检出到本地的，那么就不需要再次关联了。本场景适用于，你本地有代码库，需要首次提交到远程仓库中。

### 1. 创建本地仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-06.png?raw=true" width="750px">
</div>

- 首先你需要打开 IntelliJ IDEA 工程，选择 VCS 创建一个本地仓库的Git仓库。Create Git Repository

### 2. 关联远程仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230707-07.png?raw=true" width="750px">
</div>

- 打开你的 Gitee 仓库对应的项目，复制项目 HTTPS 地址，粘贴到 IntelliJ IDEA 项目的远程仓库配置中，点击 OK 即可。
- Manage Remotes 可以设置多个仓库，在push代码的时候，选择对应的地址提交即可。

### 3. 项目代码提交

#### 3.1 添加

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-08.png?raw=true" width="750px">
</div>

- 在工程上右键，把你需要提交的文件，选择 +Add 注意不要把一些不需要提交的文件，也提交上去。
- 你可以先创建一个 `Add to .gitignore` 它可以屏蔽掉一些不要的文件。—— 在 Github 创建工程的时候也有此文件。你也可以先更新 pull 拉取下来。

#### 3.2 提交

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-09.png?raw=true" width="750px">
</div>

- 提交代码快捷键：`Ctrl + K` - 提交到本地仓库

#### 3.3 推送

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-10.png?raw=true" width="750px">
</div>

- 推送代码快捷辑：`Ctrl + Shift + K` —— 提交到远程仓库

## 四、提交规范

**分支命名**：`日期_姓名首字母缩写_功能单词`，如：`230708_xfg_buildFramework`

**提交规范**：`作者，type: desc` 如：`小傅哥，fix：修复查询用户信息逻辑问题` *参考Commit message 规范*

```
# 主要type
feat:     增加新功能
fix:      修复bug

# 特殊type
docs:     只改动了文档相关的内容
style:    不影响代码含义的改动，例如去掉空格、改变缩进、增删分号
build:    构造工具的或者外部依赖的改动，例如webpack，npm
refactor: 代码重构时使用
revert:   执行git revert打印的message

# 暂不使用type
test:     添加测试或者修改现有测试
perf:     提高性能的改动
ci:       与CI（持续集成服务）有关的改动
chore:    不修改src或者test的其余修改，例如构建过程或辅助工具的变动
```

---

**此外**，Github 是一个大宝藏，你可以通过检索，找到特别多的优质项目、代码、设计。如：[https://github.com/fuzhengwei](https://github.com/fuzhengwei)

---

### Md Road Map Github Actions Workflows (`docs/md/road-map/github-actions-workflows.md`)

---
title: Docker 镜像构建 - Github Action
lock: need
---

# Docker 镜像构建 - Github Action

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

最近看到不少研发伙伴，因为 DockerHub 拉取镜像失败，不能愉快的「👨🏻‍💻凿代码」了而头疼。但这种也就只能拦住`小卡拉米`程序员，高阶的码农有太多种方式让自己愉快的敲代码。就像 Maven 很慢，我可以自建 Maven 仓库。GitHub 很慢，我们可以自建 Gitlab。同样 Docker 很慢，我们还是可以自建 Docker 仓库哇🤩。—— 一套免费自建方案，满足个人开发诉求。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-01.png" width="150px">
</div>

**小白基础很差，每次收获都很大！**

很多我们自己不能直接访问的服务，在很多互联网公司中都是可以直接访问的，包括；GitHub、谷歌，因为这些公司都是有专门备案的可信的专线网络。这也就是为什么很多机智的伙伴，有 github 地址，但访问很慢的时候，会直接在 gitee 仓库，通过导入 github 地址的方式进行访问。因为 gitee 是有对应的网络专线的，他们可以来拉取代码（并做安全审核），让我们可以放心使用。

嘿嘿，那么就有办法了。同样的访问不了 DockerHub，拉取不了进项。但阿里云有镜像仓库呀。阿里云可以访问 GitHub，GitHub 也可以访问阿里云。那么简单了，我们可以基于 GitHub 的 Actions 服务，执行构建和推送镜像的脚本，把需要的镜像推送到阿里云 Docker 镜像仓库，这不就可以满足自己使用了吗！

>接下来，小傅哥就教大家搞一下这个事情。—— 学到手的全是技术！

## 一、GitHub Actions 是什么

我把 GitHub Actions 当成一种免费的云服务器，我估计不少程序员也都这么理解！因为它可以执行出非常多的骚操作！

**正经的！** GitHub Actions 是 GitHub 提供的一项持续集成和持续交付（CI/CD）服务。它允许开发者在代码库中自动化各种任务，例如构建、测试和部署代码。通过定义工作流（workflow），开发者可以在特定事件（如代码推送、拉取请求等）发生时自动触发这些任务。

嘿嘿，你看，其实还是一台可以执行任意脚本的云服务器！除了说的 CI/CD 持续交付，也包括它可以定时的执行的任意脚本，比如；定时执行 Java 的 Main 函数，调用下 openai 接口，给自己的公众号每天推送一个最新的技术信息。或者是各类签到就送东西的平台，定时+随机时间签到获取金币/京豆/积分。

## 二、GitHub Actions  的使用

小傅哥不只是一个后端Java工程师，同时也能开发点前端，再搞点实施运维的事情。这就让我对很多问题，都有了很多的解决方案。

所以在小傅哥星球「码农会锁」带着大家实战的大营销平台项目，就提供了多种的 Docker 部署方式。如；本地构建再推送镜像到 DockerHub，鉴于不少伙d伴本地安装 Docker 费劲，又提供了直接把一台云服务器配置成开发机器，在云服务器直接 Maven 编译和构建镜像，这样就满足了大部分伙伴的开发部署诉求。

当为了让伙伴得到更全面的学习，小傅哥最近又开始提供了 GitHub Actions CI/CD 持续交付的部署方式。只要你提交代码，即可自动进行构建和完成镜像的推送，并且是同时把镜像推送到 DockerHub 和 阿里云的 Docker 镜像中。接下来小傅哥就告诉大家是怎么操作的。

### 1. 阿里云镜像仓库配置

#### 1.1 创建个人实例

- 地址：[https://cr.console.aliyun.com/cn-hangzhou/instances](https://cr.console.aliyun.com/cn-hangzhou/instances)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-02.png" width="750px">
</div>

#### 1.2 查看连接凭证

- 地址：[https://cr.console.aliyun.com/cn-hangzhou/instance/credentials](https://cr.console.aliyun.com/cn-hangzhou/instance/credentials)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-03.png" width="750px">
</div>

#### 1.3 镜像使用说明 - 推送后即可使用

- 地址：[https://cr.console.aliyun.com/repository/cn-hangzhou/fuzhengwei/big-market-app/details](https://cr.console.aliyun.com/repository/cn-hangzhou/fuzhengwei/big-market-app/details) - `修改为你的地址进行登录`
- 使用：`docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/big-market-app:3.0`

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-04.png" width="750px">
</div>

### 2. GitHub 仓库 Actions CI/CD 配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-05.png" width="750px">
</div>

- 首先，点开你的 GitHub 中需要使用 Actions 的项目，点击 Settings 设置。
- 之后，添加阿里云镜像仓库配置，包括用户名和密码。[https://cr.console.aliyun.com/cn-hangzhou/instance/credentials](https://cr.console.aliyun.com/cn-hangzhou/instance/credentials)
- 最后，配置 DockerHub 用户名和 `New Access Token`。[https://hub.docker.com/settings/security](https://hub.docker.com/settings/security)

### 3. 工程脚本配置

#### 3.1 工程目录

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-06.png" width="450px">
</div>

- 新增加了一个 ActionDockerfile 方便管理路径。

#### 3.2 Dockerfile

```java
# 基础镜像
FROM openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用
ADD ./big-market-app/target/big-market-app.jar /big-market-app.jar

ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /big-market-app.jar $PARAMS"]
```

#### 3.3 workflows

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 这里就是 GitHub 的 Actions 执行脚本，包括；监听 master 分支、拉取代码、设置环境、Maven 打包、构建镜像、推送镜像分别到 DockerHub 和 阿里云镜像仓库。
- 这样我们每次需要新的打包镜像时，可以直接在这里修改下版本号，提交即可。

### 4. 启动运行

GitHub 的 Actions 是自动执行的，只要监听到 Master 分支有变化，即可自动执行并推送镜像到仓库中。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-07.png" width="650px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-08.png" width="650px">
</div>

> 运行到这里，你就可以在 DockerHub、阿里云仓库同时看到自己的镜像文件了。想咋用就咋用。

## 三、GitHub Actions 其他玩法

### 1. 同步镜像文件

- 地址：[https://github.com/fuzhengwei/docker-image-pusher](https://github.com/fuzhengwei/docker-image-pusher)

```
mysql:8.0.32
phpmyadmin:5.2.1
redis:6.2
spryker/redis-commander:0.8.0
rabbitmq:3.12.9
```

1. 在 `images.txt` 添加你需要的镜像（PR方式提交），你可以从 https://hub.docker.com/ 搜索需要的镜像后添加。
2. 新添加镜像，需要等待1分钟同步。之后通过命令 `docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql` 拉取你需要的镜像，如果有版本号，可以添加。如；`mysql:8.0.32`

### 2. 自动部署博客

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-blog](https://github.com/fuzhengwei/xfg-dev-tech-blog)
- 视频：[https://www.bilibili.com/video/BV1ri421a7Aj/](https://www.bilibili.com/video/BV1ri421a7Aj/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-actions-workflows-09.png" width="650px">
</div>

---

### Md Road Map Github Models (`docs/md/road-map/github-models.md`)

---
title: Github Models
lock: need
---

# Github Models（AI接口），申请使用教程

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

>沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

现在做 AI 应用开发的小伙伴越来越多了，随之而来的是对 LLM 大模型接口的使用依赖。一般的模型，可能会让程序出现幻觉。而高质量的模型，大部分是需要付费，比如 `openai/gpt-5`、`azureml-xai/grok3`、`azureml/Phi-4` 等。**那怎么办！？🤔**

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-springcloud-feign-01.gif" width="150px"/>
</div>

这些免费的不错的大模型（LLM），也都是有对应的频次和最大出入/输出token的限制。虽然不会让咱们玩命的调用测试。但在程序开发初期，对于单个功能的验证还是非常方便的。接下来，小傅哥就给大家演示下，关于 Github 免费提供的大模型如何配置使用。

## 一、模型说明

### 1. 官网地址

官网：[https://github.com/marketplace?type=models](https://github.com/marketplace?type=models)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-01.png" width="750px"/>
</div>

在 Github marketplace 下提供了非常多的免费的 LLM 使用，gpt-5、gpt-4.1 都是有的，具备完整的测试功能。有时候还会新增加其他模型。

### 2. 频次限制

地址：[https://docs.github.com/en/github-models/use-github-models/prototyping-with-ai-models#rate-limits](https://docs.github.com/en/github-models/use-github-models/prototyping-with-ai-models#rate-limits)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-02.png" width="750px"/>
</div>

- 每日150次、每分钟15次，每次token，8000进、4000出。对于单个模型的验证是没问题的，不过对于复杂的 ai agent 智能体是跑不动的。所以，这块测试的话，要分开验证。之后对于全流程的，在购买 api 进行测试即可。
- 如果小伙伴还觉得，每分钟15次，有点不够干的，那你可以弄10个账号，通过 nginx 负载下，这样基本每分钟150次，一天1500次还是很够用的。

## 二、模型使用

### 1. 测试工程

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-06.png" width="650px"/>
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-github-models](https://github.com/fuzhengwei/xfg-dev-tech-github-models)
- 说明：这里小傅哥准备了一套基于 Spring AI 的测试工程，来验证 Github LLM 的使用。你可以下载后，替换 token/apikey 即可调用验证。
- 环境：jdk 17、maven 3.8.x、spring ai 1.1.0

### 2. 对接申请

#### 2.1 申请token

地址：https://github.com/settings/tokens/new

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-03.png" width="750px"/>
</div>

- 在 Tokens 下，添加 Note 描述和过期时间，完事后不用加任何其他权限，拉到最后设置点击 `Generate token` 生成令牌即可。
- 生成后复制你的 Token，复制后关闭就看不见了。只有删除和创建新的。

#### 2.2 查看curl（api）

地址：[https://github.com/marketplace/models/azure-openai/gpt-4-1/playground](https://github.com/marketplace/models/azure-openai/gpt-4-1/playground)

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-04.png" width="750px"/>
</div>

在左侧你可以选择需要使用的模型，之后进行对话验证。之后，在右侧有一个 `Use this model` 这里可以获得模型 API 请求信息。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-05.png" width="750px"/>
</div>

你现在单独验证 api，在整个程序测试前，要确保你的 api 是可用的。

### 3. 测试验证

```java
public class ApiTest {

    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Resource resource = new ClassPathResource("dog.png", classLoader);

        OpenAiApi openAiApi = OpenAiApi.builder()
                .baseUrl("https://models.github.ai/inference")
                // apikey 要替换为你的，在 https://github.com/settings/tokens 创建即可。
                .apiKey("ghp_FfiwBkVunYDQyhIwaQSccVw******")
                .completionsPath("/chat/completions")
                .embeddingsPath("/embeddings")
                .build();

        ChatModel chatModel = OpenAiChatModel.builder()
                .openAiApi(openAiApi)
                .defaultOptions(OpenAiChatOptions.builder()
                        .model("openai/gpt-4.1")
                        .build())
                .build();

        // 模型测试，没问题可以识别图片
        ChatResponse response = chatModel.call(new Prompt(
                UserMessage.builder()
                        .text("请描述这张图片的主要内容，并说明图中物品的可能用途。")
                        .media(Media.builder()
                                .mimeType(MimeType.valueOf(MimeTypeUtils.IMAGE_PNG_VALUE))
                                .data(resource)
                                .build())
                        .build()));

        System.out.println("测试结果" + JSON.toJSONString(response));

    }

}
```

```java
测试结果{"metadata":{"empty":false,"id":"chatcmpl-CzHhVYaXPv3HjJ3oKE4YKPamPQRQB","model":"gpt-4.1-2025-04-14","rateLimit":{"requestsLimit":1000,"requestsRemaining":996,"tokensLimit":1000000,"tokensRemaining":980423},"usage":{"completionTokens":0,"nativeUsage":{},"promptTokens":0,"totalTokens":0}},"result":{"metadata":{"contentFilters":[],"empty":true,"finishReason":"STOP"},"output":{"media":[],"messageType":"ASSISTANT","metadata":{"role":"ASSISTANT","messageType":"ASSISTANT","finishReason":"STOP","refusal":"","index":0,"annotations":[{"$ref":"$.metadata.rateLimit.usage.nativeUsage"}],"id":"chatcmpl-CzHhVYaXPv3HjJ3oKE4YKPamPQRQB"},"text":"这张图片的主要内容是一只卡通风格的小狗。小狗是棕色的，脸部较大，眼睛圆而突出，表情看起来有些疑惑或惊讶，嘴巴微微张开，尾巴翘起。整个形象简洁可爱，线条和颜色运用都比较简单。\n\n**物品的可能用途：**\n1. **图标或表情包**：这种卡通形象常用于聊天软件中的表情包或头像，传达惊讶、困惑等情感。\n2. **儿童绘本或动画角色**：可以作为儿童图书或动画中的形象角色，吸引小朋友的注意力。\n3. **宠物相关宣传设计**：可用于宠物店、宠物产品的宣传海报、包装或logo，增加亲和力。\n4. **教育材料**：在教学课件或教育类APP中，用于引导、示范或者增加趣味性。\n\n整体而言，这是一种很常见且可爱的卡通动物形象，主要用于与宠物、儿童或者情感表达相关的领域。","toolCalls":[]}},"results":[{"$ref":"$.metadata.rateLimit.usage.nativeUsage.result"}]}
```

- 这是一段基于 Spring AI 配置 github llm api的使用方式，尤其注意，baseUrl、apiKey、completionsPath、embeddingsPath、openai/gpt-4.1，这些配置信息和你直接使用管的 gpt 配置是有差异的。
- 本案例，是识别图片的用途，你也可以验证其他功能。这样的项目在小傅哥的 [《AI Agent 智能体》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 都有讲解。

## 三、使用拓展

### 1. 部署脚本

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-08.png" width="750px"/>
</div>

- 这是一套 nginx 转发脚本。你需要有自己的域名（各个云服务器厂商都可以购买）以及申请 ssl 后才可以配置使用。
- ssl 可以从 [httpok](https://bugstack.cn/md/road-map/ssl-httpsok.html) 申请使用。地址：[https://bugstack.cn/md/road-map/ssl-httpsok.html](https://bugstack.cn/md/road-map/ssl-httpsok.html)

### 2. 转发说明（nginx）

如果你希望在使用的过程中，让模型是以你之前使用 openai 一样的方式，那么可以配置一套 Nginx 转发；

```java
server {
    listen       80;
    listen  [::]:80;
    server_name  需要配置域名（api.xxx.cn）;

    rewrite ^(.*) https://$server_name$1 permanent;

}

server {
    listen       443 ssl;
    server_name  需要配置域名（api.xxx.cn）;

    ssl_certificate      /etc/nginx/ssl/_.itedus.cn.pem;
    ssl_certificate_key  /etc/nginx/ssl/_.itedus.cn.key;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /v1/ {
        # 去掉路径中的/v1前缀
        rewrite ^/v1/(.*) /$1 break;
        proxy_pass https://models.inference.ai.azure.com;
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

- nginx 的方式是，当访问有 v1/ 路径的时候，在进行路径重写 `rewrite ^/v1/(.*) /$1 break;` 之后转发到 `https://models.inference.ai.azure.com` - `这个也是 gpt 里的一种模型对接地址`
- 转发后，你就可以直接使用模型服务了。

### 3. curl 验证

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-github-modes-07.png" width="750px"/>
</div>

- 配置转发后，就可以使用 curl_nginx.sh 脚本进行验证了。

好啦，本文到这，你就可以初步使用免费的 LLM 进行一些一些初始功能验证。2025年，ai agent 开始崛起，2026年，必然是 ai agent 爆发的时候。一定要多学习这类实战项目，企业里 spring 是大盘，所以结合 spring ai 做的项目也必然会非常多。

---

### Md Road Map Github (`docs/md/road-map/github.md`)

---
title: Github
lock: need
---

# Github 使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

没用过 Github 不能算是一个正经码农！

Github 本身是的核心职责是一个在线软件源代码托管服务平台，也就是说你的本地开发的代码可以提交到 Github 让多人参与维护和迭代。但除了这个核心的功能外，还提供了不少的社交功能，如；点赞、关注、评论、复刻等，而且 Github 男性用户居多，为此也让Github 被称呼为 Gayhub 社群。

在使用Github时，你需要注册一个账号，之后创建一个用于存放代码的仓库，之后就可以把你的代码提交到仓库了。而其他参与此项目的伙伴，也可以通过你的仓库地址检出项目。当然你也可以检出其他人的项目。

- 仓库配置 SSH 参考：[https://bugstack.cn/md/road-map/git.html](https://bugstack.cn/md/road-map/git.html)

## 一、账号注册

- 官网：[https://github.com](https://github.com/)
- 注册：[https://github.com/signup?source=login](https://github.com/signup?source=login)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-01.png?raw=true" width="750px">
</div>

- 你可以按照Github的注册提示，一步一步的填写信息就可以完成账号注册了。
- 注册后你就会有一个自己的 Github，如：[https://github.com/fuzhengwei](https://github.com/fuzhengwei)

## 二、仓库创建

### 1. 创建类型

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-02.png?raw=true" width="550px">
</div>

- New repository 创建仓库
- Import repository 导入仓库
- New organization 创建组织，一个组织下可以创建多个项目。

### 2. 创建操作

#### 2.1 创建项目

**创建选项**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-03.png?raw=true" width="550px">
</div>

- 项目名称：不重复即可，一般是小写的项目名称和中划线。
- 项目介绍：介绍写核心信息。
- 项目类型：公开的和私有的，私有的别人不能被搜索到，也看不到。
- 详细介绍：README 是用于写详细介绍的，你可以把它当成是项目本身的简历。
- .gitignore：是一个模板，哪里不被 Java 项目提交到仓库。
- License：协议，比如 Apache License 协议。

**创建完成**

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-04.png?raw=true" width="550px">
</div>

- 示例：[https://github.com/fuzhengwei/xfg-frame-ddd](https://github.com/fuzhengwei/xfg-frame-ddd)

#### 2.2 创建组织

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-05.png?raw=true" width="550px">
</div>

- 组织相当于是一个额外的空间，而你是这个组织的管理者。它必须全局唯一。
- 之后你可以在创建项目的时候，选择到组织空间，这样项目就会创建到组织里了。

## 三、代码提交

代码提交到仓库，核心在于把本地代码和远程仓库关联起来。如果你是直接从远程仓库地址，检出到本地的，那么就不需要再次关联了。本场景适用于，你本地有代码库，需要首次提交到远程仓库中。

### 1. 创建本地仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-06.png?raw=true" width="750px">
</div>

- 首先你需要打开 IntelliJ IDEA 工程，选择 VCS 创建一个本地仓库的Git仓库。Create Git Repository
- 这里还有一个分享到仓库，Share Project On GitHub 你也可以选择使用，直接把本地代码分享创建到远程仓库。

### 2. 关联远程仓库

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-07.png?raw=true" width="750px">
</div>

- 打开你的Github 仓库对应的项目，复制项目 HTTPS 地址，粘贴到 IntelliJ IDEA 项目的远程仓库配置中，点击 OK 即可。

### 3. 项目代码提交

#### 3.1 添加

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-08.png?raw=true" width="750px">
</div>

- 在工程上右键，把你需要提交的文件，选择 +Add 注意不要把一些不需要提交的文件，也提交上去。
- 你可以先创建一个 `Add to .gitignore` 它可以屏蔽掉一些不要的文件。—— 在 Github 创建工程的时候也有此文件。你也可以先更新 pull 拉取下来。

#### 3.2 提交

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-09.png?raw=true" width="750px">
</div>

- 提交代码快捷键：`Ctrl + K` - 提交到本地仓库

#### 3.3 推送

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-230706-10.png?raw=true" width="750px">
</div>

- 推送代码快捷辑：`Ctrl + Shift + K` —— 提交到远程仓库

## 四、提交规范

**分支命名**：`日期_姓名首字母缩写_功能单词`，如：`230708_xfg_buildFramework`

**提交规范**：`作者，type: desc` 如：`小傅哥，fix：修复查询用户信息逻辑问题` *参考Commit message 规范*

```
# 主要type
feat:     增加新功能
fix:      修复bug

# 特殊type
docs:     只改动了文档相关的内容
style:    不影响代码含义的改动，例如去掉空格、改变缩进、增删分号
build:    构造工具的或者外部依赖的改动，例如webpack，npm
refactor: 代码重构时使用
revert:   执行git revert打印的message

# 暂不使用type
test:     添加测试或者修改现有测试
perf:     提高性能的改动
ci:       与CI（持续集成服务）有关的改动
chore:    不修改src或者test的其余修改，例如构建过程或辅助工具的变动
```

---

**此外**，Github 是一个大宝藏，你可以通过检索，找到特别多的优质项目、代码、设计。如：[https://github.com/fuzhengwei](https://github.com/fuzhengwei)

---

### Md Road Map Google Adk (`docs/md/road-map/google-adk.md`)

---
title: google adk
lock: need
---

# Google Agent ADK，20分钟，帮你搭建一个简单智能体

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

💐 从22年至今，小傅哥已经带着大家做了5个AI类项目，包括；`（22年）问答助手`、`（23年）OpenAI应用（含支付、敏感词过滤）`、`（24年）AI 代码自动评审`、`（25年）Ai Agent 智能体`、`（25年）Ai MCP Gateway 网关`。

这些项目也都是结合这，AI 这一年最新的技术动向和应用方向，而做的设计和落地。所以，每次小傅哥都给大家讲了，接下来 AI 将影响的一些场景，也都陆续的发生了。就像，24年11月发布 MCP 协议后，我给大家说，所有互联网企业都将大量的落地 MCP 服务，并开始 Ai Agent 智能体实现（别看市面有 dify、扣子，各个且用还是要做自己的业务智能体）。

随后，25年年初，小傅哥就带着大家开始了 RAG、MCP、Ai Agent 智能体的开发，并告诉大家，以后 Ai Agent 智能体也会出标准的框架，让开发更加容易。这不，**谷歌的 ADK 就来了**。并且这哥们👬🏻还定义A2A协议。这会让不是那么大型的互联网公司，也会具备 Ai Agent 智能体开发的能力。

接下来的几年，所有的业务项目，都会以 Ai Agent 智能体翻一遍，程序员新增的岗位和工作量仍然会很多。因为在咱们这，你做的越快，你就得做的越多！

>接下来，小傅哥就带着大家做一下 Google ADK 搭建 AI Agent。如果你感兴趣 AI 类项目，还可以在文末获取全部实战项目源码，深度积累此类技术内容。**文末有Google ADK 运行效果，交互式对话智能体，对 ELK 进行巡检分析。**

## 一、官网资料

- 官网：[https://google.github.io/adk-docs/](https://google.github.io/adk-docs/)
- 搭建：[https://google.github.io/adk-docs/get-started/](https://google.github.io/adk-docs/get-started/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-01.png" width="750px">
</div>

- ADK 以轻便化构建 Ai Agent 智能体，解决智能体开发的复杂流程而设计。目前支持 Python、Java、Go 3种语言对应的技术框架。
- 整个文档完整的描述了，智能体的创建和运行、工具的调用（tools、function、mcp）、可观测性以及 A2A 协议等。
- Agent Development Kit (ADK) is designed to empower developers to quickly build, manage, evaluate and deploy AI-powered agents. These quick start guides get you set up and running a simple agent in less than **20 minutes**.

## 二、工程实践

### 1. 前置说明

本次的 Ai Agent 实践，是以 Google ADK 框架为基础，配和 Github [system-prompts-and-models-of-ai-tools](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools) 开源提示词项目中的 claude-code-system-prompt 作为必要描述。来实验，ELK 系统日志智能分析场景。

- API Key：[https://ai.google.dev/gemini-api](https://ai.google.dev/gemini-api) 需要申请开发 API 秘钥，是免费的。
- Docker 环境，本项目部署了一套 ELK 日志服务，基于 Docker 部署，之后对 ELK 模拟写入日志，让 Ai Agent 智能体进行分析。`如果暂时配置不了，可以在测试的时候去掉这部分 mcp 服务`
- `JDK 17+`、`Maven 3.8.x`

### 2. 工程说明

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-02.png" width="950px">
</div>

- 工程地址：[https://github.com/fuzhengwei/xfg-dev-tech-google-adk](https://github.com/fuzhengwei/xfg-dev-tech-google-adk)
- 这是一套引入了 Google ADK 0.1.0 版本的 Agent 最基础智能体测试。如果需要扩展，还要额外增加很多东西，可以参考 [《Ai Agent 智能体项目》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html)

#### 2.1 YML 配置

```java
server:
  port: 8901

# 可申请API秘钥；https://ai.google.dev/gemini-api
google:
  api:
    base-url: https://generativelanguage.googleapis.com
    key: AIzaSyDF6JnvFx7xWEsARS*******可以自己申请免费的
  cloud:
    project: xfg-google-adk

logging:
  level:
    root: info
  config: classpath:logback-spring.xml
```

- 在 `application-dev.yml` 修改你的参数配置，配置你的 Google api key

#### 2.2 ADK 单测

```
/* Detailed source-code truncated for AI context efficiency. */
```

```java
Agent > Hi there! Yes, I'm here to help.  To best assist you, could you tell me what you need help with?  The more information you give me, the better I can understand your request and provide a useful response.
```

- 这是一套最基础的 Ai Agent 智能体 ADK 的测试使用代码。其实它的配置和调用与 Spring AI 框架是有类似之处的，基本上这类框架也都是这样的使用模式。
- LlmAgent 提供了一整套构建智能体的方式，可以设置客户端（Gemini），并设置相关的 baseUrl、apiKey 参数，以及模型和超时时间等。
- InMemoryRunner 的用途是把 Agent 放入一个记忆执行里，让一整个 Session 会话下的执行都被记录下，这样才能记录上下文。
- 之后就是放到响应框架进行之后和拿到最后结果啦。

#### 2.3 Agent 智能体测试

```
/* Detailed source-code truncated for AI context efficiency. */
```

- AutoAgentTest 智能体，配置了两个 mcp，mcp_elk、mcp_filesystem 服务。其实 AI Agent 智能体，都少不了 MCP 服务的加持，这样才能让这个大脑有手脚可以行动起来。
- init 初始化阶段，instruction 配置了对应的智能体提示词，这部分很重要，有点像智能体的神经。[https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Claude%20Code/claude-code-system-prompt.txt](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Claude%20Code/claude-code-system-prompt.txt) - 可以选择这里的提示词配置到智能体进行测试。
- 这部分也可以运行测试，之后会你可以进行提问。注意，如果你没有配置 elk，那么可以删掉 `mcpTools.addAll(mcp_elk());` 代码。
- mcp_filesystem() 配置了，`/Users/fuzhengwei/Desktop` 你需要修改为你的本地的有权限访问的地址。

#### 2.4 Agent 智能体服务

有了前面的案例测试基础，就可以把服务配置成对应的接口，以及开发个简单的页面进行对接验证了。

##### 2.4.1 服务接口

```java
@Slf4j
@RestController
@RequestMapping("/trigger")
@CrossOrigin(origins = "*")
public class AgentController {

    private final AgentService agentService;

    public AgentController(AgentService agentService) {
        this.agentService = agentService;
    }

    @PostMapping(path = "/session", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public CreateSessionResponse createSession(@RequestBody CreateSessionRequest req) {
        String sessionId = agentService.createOrGetSession(req.getUserId());
        log.info("创建会话ID:{}", sessionId);
        return new CreateSessionResponse(sessionId);
    }

    @PostMapping(path = "/chat", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ChatResponse chat(@RequestBody ChatRequest req) {
        String sessionId = req.getSessionId();
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = agentService.createOrGetSession(req.getUserId());
        }
        log.info("使用会话ID:{}", sessionId);
        List<String> outputs = agentService.chat(req.getUserId(), sessionId, req.getMessage());
        return new ChatResponse(sessionId, String.join("\n", outputs));
    }
}
```

- 这里就是把单测的服务，包装成接口。详细的部分可以直接看工程代码。

##### 2.4.2 页面对接

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-03.png" width="950px">
</div>

- 把服务端的接口对接到页面。

## 三、功能测试

### 1. 部署 elk 日志服务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-04.png" width="950px">
</div>

- 整个 Ai Agent 案例，配置了 ELK 作为日志分析的基础，所以最好配置下。
- 这里也有云服务器的部署操作，也可以参考教程来部署。教程：[https://bugstack.cn/md/road-map/docker-install.html](https://bugstack.cn/md/road-map/docker-install.html)
- 注意配置完成后，要执行 `elk-blacklist-data.sh` 模拟的写入进去一些日志，这样才能用于分析使用。

### 2. 启动服务访问页面

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-05.png" width="700px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-google-adk-06.png" width="700px">
</div>

- 以上演示了，使用 Ai Agent 进行 ELK 日志分析，通过对话可以看到，最终我们可以拿到系统的日志数据。
- 你还可以尝试配置其他的 MCP 服务，之后验证各种场景功能。担任如果你希望更细化的做 Ai Agent，还是要看下 [《Ai Agent 智能体项目》](https://bugstack.cn/md/project/ai-knowledge/ai-knowledge.html) 这样可以更细腻的做出这样的系统，以及对应的可视化编排操作。

---

### Md Road Map Grafana (`docs/md/road-map/grafana.md`)

---
title: Grafana 可视化监控面板
lock: need
---

# Prometheus + Grafana 监控，验证 Hystrix 超时熔断

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?isOutside=true&aid=663912853&bvid=BV1Na4y1f7cr&cid=1344706883&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，使用 Prometheus + Grafana 部署监控，同时结合监控了解到为什么需要使用 Hystrix 对接口进行超时熔断处理。

很多伙伴在面试的时候，都可能会被问到；你的应用接口响应时间多少，Tomcat 配置了多少连接数，如果接口超时了怎么办，会不会把服务拖垮。那会不会呢，其实会的，对于一些接口不稳定容易超时但又不熔断的接口，在用户大量请求的情况下，是很容易把Tomcat连接数打满，直至拖垮整个服务，让服务的任何接口都没有响应。所以本节小傅哥会带着大家，来模拟这样的场景，让大家学习下。

本文涉及的工程：
- xfg-dev-tech-grafana：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-grafana](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-grafana) - `测试工程、监控Docker安装脚本、Grafana监控面板配置JSON`

## 一、你是怎么挂的？

Tomcat 可分配的连接数就像厕所的坑位，一堆用户来上大号。本来4个坑位也够用了，因为用户来了也可以快速释放请求，不会长时间占用。但突然有这么一天，用户都拉肚子，一个进去就1个小时候，其余人都排队。最后给压垮了！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-01.png?raw=true" width="550px">
</div>

那是不是，增加了连接数(WC 更多的坑位就好了呢)，其实也好不哪去，你总不能给所有的用户都建一个坑位，而且坑位越多，距离也越长了，这就会涉及到线程的切换，也是不小的资源消耗。

所以，为了保护我方Tomcat(WC 坑位)，则需要快速熔断，而不是让它一直占用着链接不释放。

## 二、工程环境配置

这里小傅哥做一个 SpringBoot 工程测试案例，并配合添加 Hystrix 熔断组件，以及使用 Grafana 监控来观察简单压测时连接数的消耗和接口性能的反馈。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-02.png?raw=true" width="450px">
</div>

- 环境；jdk 1.8、Maven 3.6.x、Docker 环境
- 代码；在 xfg-dev-tech-grafana 测试工程中提供了测试代码和环境安装

### 1. 配置修改

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-07.png?raw=true" width="650px">
</div>

- 首先，你需要打开 prometheus.yml 修改监控采集应用的IP地址。这个配置还可以监控例如 MySQL 和其他应用。

### 2. 安装监控

文件：`docker-compose.yml`

```java
version: '3'
# 执行脚本；docker-compose -f docker-compose.yml up -d
# 拷贝配置；docker container cp grafana:/etc/grafana/ ./docs/dev-ops/
services:
  # 数据采集
  prometheus:
    image: bitnami/prometheus:2.47.2
    container_name: prometheus
    restart: always
    ports:
      - 9090:9090
    volumes:
      - ./etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
  # 监控界面
  grafana:
    image: grafana/grafana:10.2.0
    container_name: grafana
    restart: always
    ports:
      - 4000:4000
    depends_on:
      - prometheus
    volumes:
      - ./etc/grafana:/etc/grafana
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-03.png?raw=true" width="950px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-04.png?raw=true" width="950px">
</div>

- 这是 docker compose 执行脚本，如果你本地已经安装了 Docker 可以直接执行 安装即可。
- 注意；如果你是生产使用，则需要修改 `etc/grafana/grafana.ini` 中 datasources 为 mysql 这样在后面迁移的时候也会非常容易。

### 3. 监控配置

- 安装完监控环境以后，可以先打开 Grafana 地址：[http://127.0.0.1:4000](http://127.0.0.1:4000) - `admin/admin`

- 地址：[http://127.0.0.1:4000/dashboards](http://127.0.0.1:4000/dashboards) - 打开仪表盘，导入监控面板配置。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-05.png?raw=true" width="950px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-06.png?raw=true" width="950px">
</div>

- 打开导入面板后，把案例工程中的 JSON 复制到导入面板的 JSON 里，点击 Load 这样就配置进去了。
- 不过这会你还看不见数据，因为工程还没有启动，没有往里写入数据。

## 三、测试应用说明

### 1. 熔断配置

```pom
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.18</version>
</dependency>
```

- 这个熔断的组件，不需要引入 SpringCloud 一堆的东西，使用起来更加容易。

```java
@Configuration
public class HystrixConfig {

    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

}
```

- 引入 POM 后，添加 HystrixConfig 熔断配置。

### 2. 接口配置

这里小傅哥提供了2个接口，一个普通的查询数据接口，一个是 OpenAi 中服务的给前端异步响应结果的接口。尤其是 OpenAi 异步接口，我们在实际使用的时候，也总会有超时熔断，所以这里给大家添加上。

#### 2.1 普通接口

```java
/**
 * curl http://localhost:8091/api/hystrix/query_order_info
 */
@HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "50")
}, fallbackMethod = "queryOrderInfo_error"
)
@RequestMapping(value = "query_order_info", method = RequestMethod.GET)
public String queryOrderInfo() throws InterruptedException {
    new CountDownLatch(1).await();
    return "您的订单信息查询完毕";
}

private String queryOrderInfo_error() throws InterruptedException {
    return "Fallback Hello";
}
```

- 测试过程中，超时熔断时间，可以设置的较大一些，也可以先不添加超时熔断的注解。

#### 2.2 异步接口

```java
/**
 * curl http://localhost:8091/api/hystrix/stream
 */
@HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "150")
}, fallbackMethod = "stream_error"
)
@RequestMapping(value = "/stream", method = RequestMethod.GET)
public ResponseBodyEmitter stream(HttpServletResponse response) throws Exception {
    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();
    emitter.send("异步响应");
    new Thread(() -> {
        for (int i = 0; i < 200; i++) {
            try {
                emitter.send("hi xfg-dev-tech-grafana\r\n" + i);
                Thread.sleep(250);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        emitter.complete();
    }).start();
    return emitter;
}

public ResponseBodyEmitter stream_error(HttpServletResponse response) throws IOException {
    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();
    emitter.send("Err");
    emitter.complete();
    return emitter;
}
```

- 另外一个是一步响应接口，如果响应时间较长，则进入超时熔断方法中。

## 四、服务压测验证

### 1. 配置信息

**application.yml**

```yml
server:
  port: 8091
  # 1核2G内存，可默认配置 200；4核8G内存【accept-count=1000、max-threads=800、max-connections=10000】，线程数经验值800。线程池过大，cpu调度会消耗大量时间
  tomcat:
    mbeanregistry:
      enabled: true
    max-connections: 20 # 最大连接数  
    threads:
      max: 20         # 设定处理客户请求的线程的最大数目，决定了服务器可以同时响应客户请求的数,默认200
      min-spare: 10   # 初始化线程数,最小空闲线程数,默认是10
    accept-count: 10  # 等待队列长度
```

- 我们在 YML 文件中指定了 tomcat 的连接数配置为 20 个，处理线程最多也是20个。
- 同时还添加了监控空你暴露为true，这样 Grafana 才能监控到。

### 2. 压测工具

压测工具有很多，包括；[JMeter、ApacheBench、Siege](https://bugstack.cn/md/road-map/jmeter.html) 小傅哥已经在前面写过文章，也可以去参考使用。

不过这里为了让大家更加简单的压测下，小傅哥使用了 ApiPost 工具自带的压测，这样不需要自己再安装其他工具就可以简单压测下了。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-08.png?raw=true" width="750px">
</div>

- 你只要把2个接口配置到 ApiPost 就可以用一键压测工具进行压测。

### 3. 压测观察

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-grafana-09.png?raw=true" width="850px">
</div>

- 这里小傅哥压测了下接口 `http://localhost:8091/api/hystrix/stream` 接口。因为这个接口设置了超时，可以看见，快速的就把连接数给占满了。
- 所以如果你的应用配置的 Tomcat 连接数不合理，之后接口又容易超时，超时后又没有熔断，那么很容易就会把你的服务拖垮。很多新人在做一些对外的应用时，如果没有注意到这些，那么也是很容易宕机的。

---

### Md Road Map Guava (`docs/md/road-map/guava.md`)

---
title: guava
lock: need
---

# Guava 使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

本文的宗旨在于通过简单干净实践的方式教会读者，使用 Guava 的一些常用操作方法。这些方法也是日常使用 Guava 时最为常用的方法，如果你在使用中还有一些案例和特性，或者踩坑经验也可以在本文提交PR

本文涉及的工程：

- xfg-dev-tech-guava：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-guava](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-guava)
- Github Guava：[https://github.com/google/guava/wiki](https://github.com/google/guava/wiki)

## 一、组件介绍

Guava 是 Google 的一组核心 Java 库，其中包括新的集合类型（例如 multimap 和 multiset）、不可变集合、图形库以及用于并发、I/O、哈希、原语、字符串等的实用程序！它被广泛用于 Google 内部的大多数 Java 项目，也被许多其他公司广泛使用。—— 来自于 Guava 的介绍。

在小傅哥的小项目中使用 Guava，最常用也是非常喜欢用的就是它可以替代 Redis、MQ，在小项目中使用，这样我就不用一个项目引入过多的技术栈，包括；
1. 它有一个有时效性的缓存，可以替代 Redis 使用。
2. 他有一个 EventBus 消息总线，可以替代 MQ 使用。

此外，他还有布隆过滤器、简化的Java反射，以及一些集合和并发的操作。也是可以使用的，非常方便。

## 二、常用功能

### 1. 本地缓存

```java
@Test
public void test_cache() {
    Cache<String, String> cache = CacheBuilder.newBuilder()
            // 最大存储条数，缓存将尝试逐出最近或不经常使用的条目
            .maximumSize(10000)
            // 可以设定删除时候的权重判断
            .weigher((Weigher<String, String>) (x, y) -> x.length() - y.length())
            // 有效时间
            .expireAfterWrite(3, TimeUnit.SECONDS)
            // 记录次数
            .recordStats()
            .build();
    cache.put("xfg", "bugstack.cn");
    log.info("测试结果：{}", cache.getIfPresent("xfg"));
    cache.invalidate("xfg"); // cache.invalidateAll(); 也可以全部删除
    log.info("测试结果：{}", cache.getIfPresent("xfg"));
    log.info("测试结果：{}", cache.stats());
}
```

- 你可以自己设定有时效性的缓存对象，还可以记录次数、权重和最大条数。
- 如果你的项目不大，也不想自己实现有过期时间的缓存，那么 Guava 非常适合使用。

### 2. 事件总线

```java
@Test
public void test_eventbus() {
    EventBus eventBus = new EventBus();
    eventBus.register(new Listener());
    // 可以由其他服务推送消息，之后就可以在监听中收到了
    eventBus.post("消息总线，订单号：100001");
}
static class Listener {
    @Subscribe
    public void handleEvent(String orderId) {
        log.info("测试结果：{}", orderId);
    }
}
```

- 事件总线和MQ消息实现的效果是一致的，都是为了解耦功能流程。但 Guava 的这个组件，非常适合在自己的小项目中使用，接入成本非常低。

### 3. 并发回调

```java
@Test
public void test_ListenableFuture() throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(1);
    ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
    ListenableFuture<String> explosion = executorService.submit(() -> "finished");
    ExecutorService callBackService = Executors.newFixedThreadPool(1);
    Futures.addCallback(explosion, new FutureCallback<String>() {
        public void onSuccess(String explosion) {
            System.out.println("onSuccess");
            countDownLatch.countDown();
        }
        public void onFailure(Throwable thrown) {
            System.out.println("onFailure");
            countDownLatch.countDown();
        }
    }, callBackService);
    countDownLatch.await();
}
```

### 4. 布隆过滤器

```java
@Test
public void test_BloomFilter() {
    BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()),
            1000,
            0.01);
    // 向布隆过滤器中添加元素
    bloomFilter.put("apple");
    bloomFilter.put("banana");
    bloomFilter.put("orange");
    // 检查元素是否存在于布隆过滤器中
    System.out.println(bloomFilter.mightContain("apple"));   // true
    System.out.println(bloomFilter.mightContain("banana"));  // true
    System.out.println(bloomFilter.mightContain("orange"));  // true
    System.out.println(bloomFilter.mightContain("grape"));   // false
    // 输出布隆过滤器的统计信息
    System.out.println("Expected FPP: " + bloomFilter.expectedFpp());
    System.out.println("Number of Inserted Elements: " + bloomFilter.approximateElementCount());
}
```

### 5. 反射工具包

```java
@Test
public void test_Invokable() throws NoSuchMethodException {
    Method method = UserEntity.class.getMethod("getUserName");
    Invokable<?, ?> invokable = Invokable.from(method);
    log.info("测试结果 - 方法名称：{}", invokable.getName());
    log.info("测试结果 - 参数类型：{}", JSON.toJSONString(invokable.getTypeParameters()));
    log.info("测试结果 - 静态判断：{}", invokable.isStatic());
    // !(Modifier.isFinal(method.getModifiers()) || Modifiers.isPrivate(method.getModifiers()) || Modifiers.isStatic(method.getModifiers()) || Modifiers.isFinal(method.getDeclaringClass().getModifiers()))
    log.info("测试结果 - isOverridable：{}", invokable.isOverridable());
}
```

- 如果你开发一些组件，有不少的操作都是需要判断方法的权限范围、包的权限范围等，使用 Guava 的插件也会非常方便。

--- 

其他更多的操作可以参考仓库代码和官网文档学习，基本都是非常完整的案例。

---

### Md Road Map Higress Ai (`docs/md/road-map/higress-ai.md`)

---
title: Higress-Ai
lock: need
---

# AI(+MCP)网关，快速集成（LLM API/HTTP/RPC/Nacos）

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

**傻，是不傻？** 有些伙伴问，Dify、Coze，市面都有了，怎么公司里还要基于 Spring AI 框架，开发自己的智能体，主要原因是什么呢？🤔 

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-01.gif" width="150px">
</div>

**何止 Dify，Java JDK 都有公司自己干一套的！为啥呢？**

如果你还纠结这个事，说明你还是个小白，小卡拉米。公司干一套新的，对于企业来说，这东西叫技术资产，人才储备，所有开发的出来东西，既可以申请著作权，又可以申请技术专利。转而，就把这些专利作为企业的注册资金当做投资款抵扣了，也可以用于企业所得税的抵扣。

从公司大目标再往下看，随着 LLM 大模型的发展，以及各类框架的完善，AI 应用场景的智能体开发，会越来越标准化，且越来也有容易被实现。不再需要像最早的一些 Dify、Coze 方案那样笨重。

再者，企业需要沉淀 AI 技术能力（+人才），为公司适应各类 AI 应用场景开发做储备。而直接使用市面的产品，很多时候都没法做到快速迭代新的需求，甚至要在公司发展后期遇到极端问题，甚至还要考虑重新做技术选型以及重建。这个成本就非常大了。

所以，你能理解为啥公司都要做自己的服务平台了吧。而且，公司也非常需要一个像你一样，具备 AI 方面开发知识的研发人员。这也是为什么小傅哥，要带着你做这么多 AI 类的项目。今天分享的这套 AI MCP 网关服务，小傅哥也正在带着大家做。

>接下来，小傅哥就带着大家实践下阿里旗下 Higress AI 网关能力的使用。

## 一、网关介绍

官网：[https://higress.io/](https://higress.io/)
源码：[https://github.com/alibaba/higress](https://github.com/alibaba/higress)
文档：[https://higress.cn/ai/quick-start](https://higress.cn/ai/quick-start)

Higress AI 网关快速集成 LLM API，通过 AI 网关、API 网关及Himarket，解决模型、工具及Agent统一代理问题，并助力企业构建AI中台，加速AI落地。

这套网关服务，可以统一管理你的 LLM API 服务接口，如你访问的 OpenAI、智谱、千问、文心，都可以在Higress AI 网关做一个统一管理。另外，就是 MCP 网关能力，可以把注册的 HTTP 服务、Nacos 服务等，都可以转换为 MCP 接口服务能力，让 AI 客户端使用。

恰好，这个事小傅哥也在带着大家做一套 [《AI MCP Gateway 网关服务系统》](https://bugstack.cn/md/project/ai-mcp-gateway/ai-mcp-gateway.html) 如果想在 AI 开发方面做一些储备积累，那么一定要学习这套项目。

> 本案例会使用 docker 进行部署，如果你不了解 docker 是什么，可以阅读系列教程 [https://bugstack.cn/md/road-map/docker-what.html](https://bugstack.cn/md/road-map/docker-what.html)

## 二、网关使用

### 1. 案例工程

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-02.png" width="750px">
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-higress-ai](https://github.com/fuzhengwei/xfg-dev-tech-higress-ai)
- 说明：案例工程，提供了部署 Higress AI 网关脚本（+redis环境），以及包括工程提供了一个测试 http 接口，并配置了 swagger api 文档。网关可以支持从 swagger api json 转换为 MCP 协议结构。
- 环境：如果你是使用云服务器部署 Higress AI 网关，那么可以使用提供好的一键部署脚本安装环境 [https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install](https://gitcode.com/Yao__Shun__Yu/xfg-dev-tech-docker-install)

### 2. 接口说明

#### 2.1 swagger api

```java
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
    <version>2.5.0</version>
</dependency>
```

- 官网：[https://swagger.io/](https://swagger.io/)
- 添加 swagger api pom，项目启动后可以访问；[http://localhost:8091/swagger-ui/index.html](http://localhost:8091/swagger-ui/index.html) - 就可以看到项目的 http 接口信息了。

#### 2.2 接口开发

```java
@RestController
@CrossOrigin("*")
@RequestMapping("/api/v1/")
@Tag(name = "测试服务", description = "示例接口")
public class TestServiceController {

    private static final Logger logger = LoggerFactory.getLogger(TestServiceController.class);

    /**
     * <a href="http://localhost:8091/swagger-ui/index.html">API文档；swagger</a><br/>
     * <a href="http://127.0.0.1:8091/api/v1/to_upper_case?word=xiaofuge">API测试；http://127.0.0.1:8091/api/v1/to_upper_case?word=xiaofuge</a>
     */
    @GetMapping("to_upper_case")
    @Operation(summary = "字符串转大写", description = "将传入 word 转换为大写")
    public String toUpperCase(@RequestParam String word) {
        logger.info("接收信息:{}", word);
        return word.toUpperCase();
    }

}
```

- 在接口上增加描述信息，这些信息可以用作于 mcp 协议结构中方法和字段上的介绍。如下就是 mcp 接口的 @Tool 工具配置。

```java
@Tool(description = "获取公司雇员信息")
public XxxResponse getCompanyEmployee(XxxRequest01 xxxRequest01, XxxRequest02 xxxRequest02) {
    log.info("根据公司和雇员，查询工资和工作工时。{} {}",xxxRequest01.getCompany(), xxxRequest02.getEmployeeName());
    // 这部分可以实际调用你需要的接口，比如调用http接口获取个数据或者做一些操作等。
    XxxResponse xxxResponse = new XxxResponse();
    xxxResponse.setSalary(new Random().longs(10000).toString());
    xxxResponse.setDayManHour(String.valueOf(new Random().nextInt(24)));
    return xxxResponse;
}
```

- 所以，即使是我们自己开发 AI MCP 网关，也是在找这样的衔接点。怎么把 http 接口，借住什么标准的桥梁，转换为 mcp 协议，让用户使用起来更加简单。而 swagger api 就是中间的标准 open api 桥梁。

### 3. 网关部署

#### 3.1 脚本说明

```java
# 命令执行 docker-compose -f docker-compose-environment-aliyun.yml up -d
# docker 代理和使用文档；https://bugstack.cn/md/road-map/docker.html
version: '3.9'
services:
  # https://github.com/alibaba/higress
  # docker run -d --rm --name higress-ai -v ${PWD}:/data \
  #        -p 8001:8001 -p 8080:8080 -p 8443:8443  \
  #        higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:latest
  higress-ai:
    image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one:latest
    container_name: higress-ai
    hostname: higress-ai
    ports:
      - 8001:8001
      - 8080:8080
      - 8443:8443
    volumes:
      - ./higress-ai/data:/data
    networks:
      - my-network

  # Redis
  redis:
    image: redis:6.2
    container_name: redis
    restart: always
    hostname: redis
    privileged: true
    ports:
      - 16379:6379
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
    networks:
      - my-network
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 3

networks:
  my-network:
    driver: bridge
```

- 这里把 higress-ai 通过 docker-compose 脚本进行部署，因为部署后还需要配置 Redis 环境，基于 Redis 的 pub/sub 发布订阅能力，让网关具备分布式部署能力，所以在 docker-compose 脚本里，提供了 higress-ai、redis 的部署。
- 部署；`docker-compose -f docker-compose-environment-aliyun.yml up -d`

#### 3.2 部署网关

##### 3.2.1 部署脚本

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-03.png" width="750px">
</div>

- 如图说明，进行部署。Mac 电脑本地测试即可。如果 Windows 电脑有兼容问题，可以考虑 Linux 云服务器。[https:618.gaga.plus](https:618.gaga.plus)

##### 3.2.2 部署结果

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-04.png" width="950px">
</div>

- 部署后，访问 portainer（这个是 docker 的管理后台）

##### 3.2.3 访问网关

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-05.png" width="950px">
</div>

- 地址：[http://127.0.0.1:8001/](http://127.0.0.1:8001/) 
- 说明：首次登录需要设置下登录账号和密码，设置后登录即可。

### 4. 获取接口

#### 4.1 启动服务（springboot）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-07.png" width="650px">
</div>

- 测试：[http://127.0.0.1:8091/api/v1/to_upper_case?word=xiaofuge](http://127.0.0.1:8091/api/v1/to_upper_case?word=xiaofuge) - `把小写的xiaofuge转换为大写`
- 接口：[http://localhost:8091/swagger-ui/index.html#/%E6%B5%8B%E8%AF%95%E6%9C%8D%E5%8A%A1/toUpperCase](http://localhost:8091/swagger-ui/index.html#/%E6%B5%8B%E8%AF%95%E6%9C%8D%E5%8A%A1/toUpperCase)

#### 4.2 获取接口

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-08.png" width="650px">
</div>

- 地址：[http://localhost:8091/swagger-ui/index.html](http://localhost:8091/swagger-ui/index.html)
- 说明：启动服务后，访问 swagger 地址，你就可以拿到接口文档了。这里主要需要的就是这份json结构。

### 5. 网关配置

#### 5.1 开启网关（mcp）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-06.png" width="650px">
</div>

- 注意，在系统设置里，需要开启 mcp 网关服务。enable = true
- 另外，redis 地址，需要配置上。默认本文给的案例，是支持直接使用 redis 别名链接的，如果 redis 不是本案例安装的，则可以用 ip:port 连接。如果有密码，记得填写密码。

#### 5.2 服务来源

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-09.png" width="750px">
</div>

- 可以在网关页，配置服务来源。这里的服务来源支持多种类型，Nacos、Eureka、Zookeeper，以及我们图中这种固定地址的案例，都是可以的。
- 注意下面配置的服务协议，这里选择的是 HTTP，也支持 HTTPS，GRPC 的格式。

#### 5.3 创建服务（MCP）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-10.png" width="750px">
</div>

在 AI网关管理下，MCP 管理中，添加一个 MCP 服务。这里的用途是建一个 MCP 网关和后端服务建立起连接。

#### 5.4 添加工具（协议转换）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-11.png" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-12.png" width="750px">
</div>

- 接下来，还需要添加下工具。也就是 http 接口的具体能力。这里可以把 Swagger 的 json 文件复制过来，添加进去即可。

#### 5.5 验证接口（sse）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-13.png" width="450px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-14.png" width="450px">
</div>

在添加接口的地方，你会看到一个网关服务的地址。也就是 SSE 接入点，用于配置到 AI 客户端里。访问地址；http://127.0.0.1:8080/mcp-servers/toUpperCase/sse

**好了，到这你的 AI MCP 网关就配置成功了，你可以把各类服务端的接口转换为 MCP 协议结构进行使用。**

### 6. 接口转发（AI）

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-15.png" width="850px">
</div>

AI 网关管理里，还提供了关于 AI 接口的配置。它可以进行统一管理，适合项目的接入使用。做 AI 类的项目，可以把 AI 请求，统一用这样一套东西管理起来。

## 三、调用测试

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-higress-ai-16.png" width="850px">
</div>

```java
13:55:19.581 [main] INFO cn.bugstack.xfg.dev.tech.test.ApiTest -- 测试结果:字符串 "xiaofuge" 转换为大写后是 "XIAOFUGE"。
```

- 调用后可以看到把小写的字符串 `xiaofuge` 转换为大写的 `XIAOFUGE`
- 你也可以进入到 TestServiceController 看到调用的日志。

## 四、深入学习

目前，小傅哥也正在带着粉丝伙伴学习 AI 项目，[《AI MCP 网关》](https://origin.bugstack.cn/md/project/ai-mcp-gateway/ai-mcp-gateway.html)，就是目前在持续更新的一个实战类项目。

该项目是 AI Agent 智能体，关于 MCP 协议对接的通用网关服务项目，以解决各类业务接口便捷转换为 MCP 协议而设计实现。通过这样的配置，可以大大的简化从普通http、rpc接口到 MCP 协议的转换操作。这样的项目，也是每个互联网公司在做 AI Agent 智能体时，必备的基础设施项目。

### 1. 项目架构

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-mcp-gateway/ai-mcp-gateway-1-1-03.png" width="650px">
</div>

### 2. 工程模块

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-mcp-gateway/ai-mcp-gateway-3-6-01.png" width="650px">
</div>

### 3. 协议转换

<div align="center">
    <img src="https://bugstack.cn/images/article/project/ai-mcp-gateway/ai-mcp-gateway-3-5-01.png" width="650px">
</div>

在此项目中，小傅哥一遍带着你分析调试 Spring AI MCP 上下文源码，一边带着你写 AI MCP 网关代码。让你全面的厘清系统设计，又能亲手实现出一套 AI MCP 网关。

---

### Md Road Map Higress (`docs/md/road-map/higress.md`)

---
title: Higress
lock: need
---

# 体验下，大厂在使用功能的API网关！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=1053517776&bvid=BV1CH4y1N7UN&cid=1517926063&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

大家好，我是技术UP主小傅哥。

还是在22年的时候，小傅哥做了一套基于 Netty 协议转换和通信的 API网关，分享给伙伴们学习使用，增加一些业务开发以外的知识积累。不过很多伙伴都问过小傅哥，为啥要自研网关呢？SpringCloud Gateway 不就可以用吗？🤔 那你知道为什么自研吗？

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-01.gif" width="150px">
</div>

不少伙伴问为啥自研，😂 但其实从我进入互联网大厂，核心的分布式技术框架，几乎就全部都是公司自研。从 rpc、mq、缓存组件（配合redis集群）、配置中心、分库分表、任务调度、全链路监控，再到我们提到的 API 网关，全部的都是自研。

后来才知道，因为之前用过一些开源组件，在流程承载方面发生过重大事故。因为是开源的组件，没法对每一个细节进行把控。而全部的自研，就会有非常强的把控力度，各个细节实现都可以做具体的优化方案，同时所有的组件自研，还可以更好的串联起来使用。另外还有一个点，就是这些开源的组件，更容易被攻击，如果有漏洞要升级，那公司全升级一遍的成本，不亚于一次大规模裁员的赔偿！当然，一些中小厂还是用市面开源的就好，因为自研的成本并不低！

那么为了让大家更好的了解下大厂的API，今天我们就来体验一款大厂开发的元原生API网关。有了这样一个学习，在看API网关项目，也会更清楚自己在做什么。

- 官网：[https://higress.io/](https://higress.io/)
- 源码：[https://github.com/alibaba/higress](https://github.com/alibaba/higress)
- 部署：[https://github.com/higress-group/higress-standalone](https://github.com/higress-group/higress-standalone) - `独立运行版，用于测试`
- 案例：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-higress](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-higress) - `部署测试`

>Higress 是一套比较庞大的工程，为了让大家可以方便的体验到，小傅哥会教给大家怎么做一个独立的部署和配置网关负载。此外文末还提供了基于 Netty 的 API网关学习教程。

## 一、Higress 介绍

Higress 是基于阿里内部两年多的 Envoy Gateway 实践沉淀，以开源 [Istio](https://github.com/istio/istio) 与 [Envoy](https://github.com/envoyproxy/envoy) 为核心构建的云原生 API 网关。Higress 实现了安全防护网关、流量网关、微服务网关三层网关合一，可以显著降低网关的部署和运维成本。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-02.png" width="950px">
</div>

- **生产等级**；支持每秒请求量达数十万级的大规模场景。彻底摆脱 reload 引起的流量抖动，配置变更毫秒级生效且业务无感。
- **平滑演进**；支持 Nacos/Zookeeper/Eureka 等多种注册中心，可以不依赖 K8s Service 进行服务发现，支持非容器架构平滑演进到云原生架构。同时支持 Nginx、ServiceMesh。这些方面是非常重要的，也就是你之前部署的到各个方面的服务，都可以被 Higress 统一管理，这也是我们设计网关的目的。
- **便于扩展**；提供 Wasm、Lua、进程外三种插件扩展机制，支持多语言编写插件，生效粒度支持全局级、域名级，路由级。插件支持热更新，变更插件逻辑和配置都对流量无损。

>接下来，小傅哥就带着大家安装部署体验下。什么东西都是上手了才有感觉。

## 二、环境部署

- 云服务器：2c4g 最低，我是用的 2c8g 体验的。[https://yun.xfg.plus](https://yun.xfg.plus) - 价格实惠。
- 基础环境：Docker、Portainer、Git 【在小傅哥的 bugstack.cn 路书中都有讲解安装和使用】

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-04.png" width="950px">
</div>

- 整体安装完会如图所示。

### 1. 软件准备

#### 1.1 方式一

在你的 Linux 服务器，通过 Git 命令检出安装项目；

```java
git clone https://github.com/higress-group/higress-standalone.git
```

#### 1.2 方式二

手动下载；https://github.com/higress-group/higress-standalone/archive/refs/heads/main.zip 在通过 ssh 的 sftp 工具上传到云服务器。之后解压 unzip 

### 2. 安装 higress

#### 2.1 执行 configure.sh 

```java
[root@lavm-aqhgp9nber github]# cd higress-standalone-main/bin/
[root@lavm-aqhgp9nber bin]# ls
base.sh  configure.sh  logs.sh  reset.sh  shutdown.sh  startup.sh  status.sh  update.sh
[root@lavm-aqhgp9nber bin]# ./configure.sh
```

- 执行 ./configure.sh 后，注意选择 nacos 其他的默认值就可以，直接回车。
- 执行过程会自动检测，nacos 的安装和删掉。这些不用操作。
- 如果执行中遇到了失败或者自己选择错了，可以重新执行 ./configure.sh -r

#### 2.2 执行 startup.sh 

```java
[root@lavm-aqhgp9nber bin]# ./startup.sh
```

- 这一步就傻瓜式的了，直接就可以安装完成。

### 3. 安装 nginx

通过安装 Nginx 模拟出2个请求服务地址，如果你部署 SpringBoot 提供出 HTTP 接口也是可以。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-03.png" width="750px">
</div>

- 上传到服务器端执行脚本 `docker-compose -f nginx-docker-compose.yml up -d`

## 三、网关配置

### 1. 服务来源

这里要配置的是，通过 https://xxx/api 访问到网关服务后，要访问到哪些服务来源上。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-05.png" width="850px">
</div>

- 服务来源支持非常多的类型，包括；Nacos、Zookeeper、Consul、Eureka、固定地址、DNS 域名。这里小傅哥选择固定地址配置。
- 分别配置了 nginx-01、nginx-02 这样我们配置路由的时候可以负载到这2个地址。

### 2. 路由配置

路由配置的作用就是指定你通过网关地址负载到对应的目标服务上，这里我们会让 http://117.72.37.243/api/ 请求负载到2个 nginx 上。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-06.png" width="750px">
</div>

- 通过路由api地址，访问到目标服务。
- 这里可以配置的玩法还有很多，可以自己在尝试下。

### 3. 策略配置

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-08.png" width="850px">
</div>

- 你可以为访问自己的路由接口配置对应的插件，比如重写URl、跨域、限流等各项功能。

## 四、服务验证

- 地址：[http://117.72.37.243/api/](http://117.72.37.243/api/) - 你需要换成自己的IP地址

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-higress-07.png" width="750px">
</div>

- 首先，我在 Nginx 的 HTML 中，配置了2个不同的请求结果，一个 01、一个 02
- 之后，访问网关地址加上 /api 接下来访问就会看到结果的变化了。

>有了这个大厂网关的体验，大家就了解了一套网关是如何使用的，作用是什么啦。接下来，如果感兴趣技术的积累，想扩展下自己，也可以学习一套网关代码的实现。

## 五、网关学习

除了业务开发，小傅哥自己也是非常感兴趣于这样的网关技术组件的实现，所以在日常的工作中也积累了很多网关的设计。后来在22年做了一套轻量的网关系统，把核心的内核逻辑实现出来让大家学习。帮助了很多伙伴学习项目后找到了不错的工作。

<div align="center">
    <img src="https://bugstack.cn/images/article/assembly/api-gateway/api-gateway-220809-02.png" width="750px">
</div>

整个**API网关**设计核心内容分为这么五块；

- `第一块`：是关于通信的协议处理，也是网关最本质的处理内容。这里需要借助 NIO 框架 Netty 处理 HTTP 请求，并进行协议转换泛化调用到 RPC 服务返回数据信息。
- `第二块`：是关于注册中心，这里需要把网关通信系统当做一个算力，每部署一个网关服务，都需要向注册中心注册一个算力。而注册中心还需要接收 RPC 接口的注册，这部分可以是基于 SDK 自动扫描注册也可以是人工介入管理。当 RPC 注册完成后，会被注册中心经过AHP权重计算分配到一组网关算力上进行使用。
- `第三块`：是关于路由服务，每一个注册上来的Netty通信服务，都会与他对应提供的分组网关相关联，例如：wg/(a/b/c)/user/... a/b/c 需要匹配到 Nginx 路由配置上，以确保不同的接口调用请求到对应的 Netty 服务上。PS：如果对应错误或者为启动，可能会发生类似B站事故。
- `第四块`：责任链下插件模块的调用，鉴权、授信、熔断、降级、限流、切量等，这些服务虽然不算是网关的定义下的内容，但作为共性通用的服务，它们通常也是被放到网关层统一设计实现和使用的。
- `第五块`：管理后台，作为一个网关项目少不了一个与之对应的管理后台，用户接口的注册维护、mock测试、日志查询、流量整形、网关管理等服务。

>项目学习地址：[https://bugstack.cn/md/assembly/api-gateway/api-gateway.html](https://bugstack.cn/md/assembly/api-gateway/api-gateway.html)

---

### Md Road Map Http (`docs/md/road-map/http.md`)

---
title: http
lock: need
---

# HTTP 框架使用和场景实战 - 结合ChatGLM自动回帖！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=577179347&bvid=BV1GB4y1f7U4&cid=1299792581&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，HTTP的常用框架使用，HTTP接口快速对接方式。以及在编码实战中练习 HTTP 对数据的采集、ChatGLM对接、问题回答。这样的场景学习，非常适合以后大家在做一些智能化问答进行参考使用。

本文涉及的工程：
- xfg-dev-tech-http：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-http](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-http)
- chatglm-sdk-java：[https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java.html](https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java.html)

## 一、案例背景

虽然在分布式架构的微服务内部是RPC调用，但在对外的Web/H5等场景下，则需要使用HTTP协议进行调用。因而我们在对接公司以外的其他服务时，通常都是HTTP协议，包括你对接微信支付、ChatGLM等。当然也有少部分使用 websocket 协议。

但众所周知HTTP的调用，会涉及较多的信息配置。包括；请求头、入参、出参，而这些内容都是非对象化的设计。很多人在对接特别多的 HTTP 请求以后，自己的工程代码就会变得非常混乱。所以我们需要用一些 HTTP 框架，来解决这个场景问题，让 HTTP 的调用更加优雅。

那么本章节小傅哥会结合知识星球的接口进行案例场景学习；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-01.png?raw=true" width="650px">
</div>

1. **星球免费加入**：[https://wx.zsxq.com/dweb2/index/group/28885518425541](https://wx.zsxq.com/dweb2/index/group/28885518425541)
2. 本章节所提供的课程源码，即可复现截图中的展示内容。自动化Ai回复问答。

## 二、接口提取

接下来，小傅哥会告诉如何非常快速的使用Java代码对接上HTTP调用。—— 把🐘大象装冰箱统共分3步；

### 1. 第一步

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-02.png?raw=true" width="650px">
</div>

- 首先，在PC端谷歌浏览器，打开知识星球首页：[https://wx.zsxq.com/dweb2/index/group/28885518425541](https://wx.zsxq.com/dweb2/index/group/28885518425541)
- 之后，摁F12打开控制台，选择网络模块。
- 最后，找到 topics 接口查询。在接口上鼠标右键。**以cURL格式复制**

### 2. 第二步

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-03.png?raw=true" width="650px">
</div>

- 首先，打开 [ApiPost](https://www.apipost.cn/) 工具中，如果没有可以下载一个。
- 之后，点击左侧的导入接口，这个里面可以直接把 cURL 格式接口导入进去。
- 最后，点击**立即导入** - 导入后你就可以点击**发送**按钮测试验证了。

### 3. 第三步

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-04.png?raw=true" width="650px">
</div>

- 首先，点击生成代码，会弹出一个各类语言对接代码案例。
- 之后，在你需要的类型代码上复制生成的代码。
- 最后，把代码粘贴到Java工程中测试。这部分代码可以参考案例工程 `cn.bugstack.xfg.dev.tech.test#HttpClientTest|OKHttpTest|Retrofit2Test`

---

除此之外，你还可以使用Ai工具，来生成对接的测试代码。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-05.png?raw=true" width="850px">
</div>

- 这样的方式也是非常好用的，而且如果有运行问题，你还可以继续提问。
- 用编程经验的人用 OpenAi 会更舒服，没有编程经验的人完全依赖 OpenAi 也会遇到各种错误。

## 三、玩个场景

### 1. 需求说明

接下来，我结合所学技术锻炼下。结合星球完成一个自动Ai回贴的功能，通过定时任务扫描星球接口帖子，并对未回答且圈【@小傅哥】的帖子进行采集回答。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-06.png?raw=true" width="650px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-07.png?raw=true" width="650px">
</div>

- 这里的接口，需要用到2个：一个扫描帖子的HTTP接口，一个回复帖子的HTTP接口。
- ChatGLM部分，小傅哥已经做了 SDK 非常好对接。[https://github.com/fuzhengwei/chatglm-sdk-java](https://github.com/fuzhengwei/chatglm-sdk-java)

### 2. 工程结构

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-08.png?raw=true" width="850px">
</div>

- 首先，你可以下载工程代码，按照这个结构来看代码。
- 之后，工程中对接了 ChatGLM SDK 并做了相关的配置在YML中。此外 YML中的 ChatGLM SDK 需要的 ApiSecretKey 可以通过官网申请。之后星球的 cookie 可以通过 F12 请求头中复制 Cookie 信息。
- 最后，是 ZSXQJob 的开发使用。

### 3. 代码实现

#### 4.1 ChatGLM SDK 对接

**源码**：`cn.bugstack.xfg.dev.tech.config.ChatGLMSDKConfig`

```java
@Bean
@ConditionalOnProperty(value = "chatglm.sdk.config.enabled", havingValue = "true", matchIfMissing = false)
public OpenAiSession openAiSession(ChatGLMSDKConfigProperties properties) {
    // 1. 配置文件
    cn.bugstack.chatglm.session.Configuration configuration = new cn.bugstack.chatglm.session.Configuration();
    configuration.setApiHost(properties.getApiHost());
    configuration.setApiSecretKey(properties.getApiSecretKey());
    // 2. 会话工厂
    OpenAiSessionFactory factory = new DefaultOpenAiSessionFactory(configuration);
    // 3. 开启会话
    return factory.openSession();
}
```

- 因为我们需要一个自动的智能Ai回帖，所以需要使用到 [ChatGLM](https://github.com/fuzhengwei/chatglm-sdk-java)。当然你也可以对接其他大厂开发的 OpenAi SDK 使用。

#### 4.2 流程串联

**源码**：`cn.bugstack.xfg.dev.tech.job.ZSXQJob`

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 以上代码就是自动智能Ai回贴的流程代码，因为是做示例，所以没有按照职责边界做拆分。
- 这段代码中会扫码帖子，并对符合流程需要我【@小傅哥】回答的帖子，进行采集和回答。
- 回答帖子会创建一个线程，调用 ChatGLM 并对返回的流式数据最封装。最后在完成时候，进行回答操作。
- 注意，这里因为限定的判断了 uId = 241858242255511 所以只有@小傅哥，才会回答。你也可以通过回复帖子，查看自己的 uId 替换。
- 此外，更多的细节代码，可以参考工程。

## 四、测试验证

### 1. 环境配置

```pom
chatglm:
  sdk:
    config:
      # 状态；true = 开启、false 关闭
      enabled: true
      # 官网地址
      api-host: https://open.bigmodel.cn/
      # 官网申请 https://open.bigmodel.cn/usercenter/apikeys
      api-secret-key: 4e087e4135306ef4a676f0cce*****.sgP2D*****
      # 知识星球 Cookie 你需要获取你的 cookie 登录
      cookie: zsxq_access_token=86EB23*****
```

- 首先你需要在 application-dev.yml 配置相关的信息，这些信息可以从下面的说明中获取。
- 如果你暂时又申请不到 ChatGLM 还想测试，可以把 enabled 配置为 false

#### 1.1 获取 ChatGLM ApiSecretKey

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-09.png?raw=true" width="850px">
</div>

- 地址：[https://open.bigmodel.cn/usercenter/apikeys](https://open.bigmodel.cn/usercenter/apikeys)
- 备注：申请开通即可，很快就可以使用。

#### 1.2 获取星球 Cookie

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-10.png?raw=true" width="850px">
</div>

- 星球：[https://wx.zsxq.com/dweb2/index/group/28885518425541](https://wx.zsxq.com/dweb2/index/group/28885518425541)
- 获取：你可以在进入后，点击任意一个调用的接口，找到 Cookie 信息。
- 注意：如果你对接了模拟登录接口，还可以自动的获取 Cookie 信息。

### 2. 启动程序和回贴

#### 2.1 发个帖子

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-11.png?raw=true" width="650px">
</div>

- 注意要圈**小傅哥**发帖子，如果你程序中修改了uId 为自己，那么可以圈你提问。

#### 2.2 回复帖子

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-http-12.png?raw=true" width="850px">
</div>
- 这个是你就会看到后台会快速运行检测帖子和回答。
- 好啦，运行到这就全部完成了。你也可以去做做测试了。

---

### Md Road Map Ignite (`docs/md/road-map/ignite.md`)

---
title: Ignite
lock: need
---

# Apache Ignite —— 一种支持SQL语句的纯内存数据库！

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=363559782&bvid=BV1594y1s7Ku&cid=1269949773&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式，向读者介绍一款基于内存的分布式SQL数据库Apache Ignite的部署、使用和性能测试。

那有了Redis这样优秀的NoSql数据库，为啥还会用到Apache Ignite呢？

不知道你是否有想过一个事情，就是Redis这样的内存数据库，如果能支持SQL语句，是不是就更牛了。这样一来本身存在MySQL数据库里的数据，就可以原封不动的封到内存中使用。既保留了原有的业务逻辑，又使用上了内存读取高性能。

所以，它来了。Apache Ignite是一个兼容ANSI-99、水平可扩展以及容错的分布式SQL数据库，作为一个SQL数据库，Ignite支持所有的DML指令，包括SELECT、UPDATE、INSERT和DELETE，它还实现了一个与分布式系统有关的DDL指令的子集。Ignite的一个突出特性是完全支持分布式的SQL关联，Ignite支持并置和非并置的数据关联。并置时，关联是在每个节点的可用数据集上执行的，而不需要在网络中移动大量的数据，这种方式在分布式数据库中提供了最好的扩展性和性能。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-01.png?raw=true" width="650px"/>
</div>

本文涉及的工程：

- xfg-dev-tech-ignite：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-ignite](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-ignite)- `docs/dev-ops 提供了 mysql、ignite 安装脚本，和数据初始化操作。`
- 官网站点：[https://ignite.apache.org/](https://ignite.apache.org/) - `官网 docs 可以阅读安装和使用`
- 中文文档：[https://ignite-service.cn/doc/2.7.0/sql/](https://ignite-service.cn/doc/2.7.0/sql/) - `这是一个 Ignite 的中文站点`
- 管理工具：[DBeaver](https://dbeaver.io/download/) - `安装最新版，直接可以连接 Ignite 数据库`

## 一、案例说明

本案例中为了对比MySQL和Ignite的性能差异，以及如何同时使用两套数据库，这里小傅哥会在一个工程中分别配置出不同的数据库对应数据源的创建和MyBatis的配置用。如果说你做过小傅哥的 [DB-Router](https://bugstack.cn/md/road-map/db-router.html) 组件开发，那么也可以在组件中添加对Ignite内存数据库的路由配置。这样的使用会更加方便，也可以自动的通过注解来切换数据源的使用。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-02.png?raw=true" width="550px"/>
</div>

- SpringBoot应用的yml配置，本身默认是配置一个数据源的。但我们这里需要把Ignite也配置出数据源并让它可以结合MyBatis进行使用。所以需要做一点编码的扩展使用。`具体可以参考源码`
- 与此同时还需要考虑对 Dao、Mapper 分不同的路径进行加载使用。因为本身来说，他们就是一套东西的不同数据源使用方式。

## 二、环境安装

在安装执行 docker-compose.yml 脚本之前，你需要先在本地安装 [docker](https://bugstack.cn/md/road-map/docker.html)之后 IntelliJ IDEA 打开 docker-compose.yml 文件，如图操作即可安装。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-03.png?raw=true" width="550px"/>
</div>

- 在 docker-compose.yml 中会先安装 MySQL 并执行 sql 文件夹里的 SQL 语句初始化数据库表。之后会安装 Ignite 环境，安装后需要用到 [DBeaver](https://dbeaver.io/download/) 连接使用。同时 compose 中还安装了一个 ApacheBench 压测工具。

## 三、连接配置

首先确保你已经安装过  [DBeaver](https://dbeaver.io/download/) ，之后就可以连接和创建表了。

### 1. 选择 Ignite

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-05.png?raw=true" width="650px"/>
</div>

### 2. 验证链接

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-06.png?raw=true" width="650px"/>
</div>

### 3. 创建库表

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-07.png?raw=true" width="650px"/>
</div>

### 4. 创建完成

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-04.png?raw=true" width="650px"/>
</div>

- 之后你所有做的修改，包括你自己手动创建表、字段、索引，都需要点保存。否则它是红色的，不生效。

## 四、功能配置

### 1. 工程结构

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-08.png?raw=true" width="850px"/>
</div>

- app层；application-dev.yml 配置多套数据源，并在 DataSourceConfig 中实现多套数据源的加载。
- infrastructure层；用于提供数据的 dao 层，这里分开2套分别提供。
- trigger；触发器层，提供了调用 Ignite、MySQL 的测试验证接口。

### 2. 数据源创建

```xml

<dependency>
    <groupId>org.apache.ignite</groupId>
    <artifactId>ignite-core</artifactId>
    <version>2.15.0</version>
</dependency>

<dependency>
    <groupId>org.apache.ignite</groupId>
    <artifactId>ignite-spring</artifactId>
    <version>2.15.0</version>
</dependency>
```

- 注意引入 ignite 的 pom 配置

#### 2.1 Ignite 

**源码**：`cn.bugstack.xfg.dev.tech.config.DataSourceConfig#IgniteMyBatisConfig`

```
/* Detailed source-code truncated for AI context efficiency. */
```

- 创建 Ignite 的数据源，以及对应的 igniteSqlSessionFactory 工厂。这样就把 MyBatis 给关联起来了。

#### 2.2 MySQL

**源码**：`cn.bugstack.xfg.dev.tech.config.DataSourceConfig#MysqlMyBatisConfig`

```java
@Configuration
@MapperScan(basePackages = "cn.bugstack.xfg.dev.tech.infrastructure.mysql.dao", sqlSessionFactoryRef = "mysqlSqlSessionFactory")
static class MysqlMyBatisConfig {
    @Bean("mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.mysql.datasource")
    public DataSource mysqlDataSource(Environment environment) {
        return DataSourceBuilder.create()
                .url(environment.getProperty("spring.mysql.datasource.url"))
                .driverClassName(environment.getProperty("spring.mysql.datasource.driver-class-name"))
                .build();
    }
    @Bean("mysqlSqlSessionFactory")
    public SqlSessionFactory mysqlSqlSessionFactory(DataSource mysqlDataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(mysqlDataSource);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mybatis/mapper/mysql/*.xml"));
        return factoryBean.getObject();
    }
}
```

- 同样，创建 MySQL 的数据源以及 MyBatis 的关联操作。

## 五、性能测试

小傅哥提供了 IgniteController、MySQLController 两个 HTTP 访问类，分别提供了两个数据库的压测操作。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-09.png?raw=true" width="950px"/>
</div>

- 这里提供了 Ignite、MySQL 的 HTTP 访问接口，分别进行压测。

### 1. Ignite 压测

- 初始化ID值：`ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start`
- 写入数据：`ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert`
- 随机加载内存1000条数据：`ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData`
- 根据加载到内存的数据查询Ignite：`ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId` - 记得给 OrderId 加索引

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-10.png?raw=true" width="650px"/>
</div>

### 2. MySQL 压测

- 初始化ID值：`ab -c 1 -n 1 http://127.0.0.1:8091/api/ignite/start`
- 写入数据：`ab -c 20 -n 50000 http://127.0.0.1:8091/api/ignite/insert`
- 随机加载内存1000条数据：`ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/cacheData`
- 根据加载到内存的数据查询MySQL：`ab -c 20 -n 1000 http://127.0.0.1:8091/api/ignite/selectByOrderId` - 记得给 OrderId 加索引

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-ignite-11.png?raw=true" width="650px"/>
</div>

---

**综上**，Ignite 略胜一筹，确实纯内存的数据库会更快一些。也适合在一些需要内存计算的场景中，并且不改变MySQL表结构的情况下，做一些优化的是使用。

---

### Md Road Map Intellij Idea Remote Jvm Debug (`docs/md/road-map/intellij-idea-remote-jvm-debug.md`)

---
title: IntelliJ IDEA Remote JVM Debug
lock: need
---

# IntelliJ IDEA Remote JVM Debug - 本地远程调试服务器运行代码

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

我遇到过一种bug场景，本地没什么问题，部署到服务器上就不行了。往往遇到这样的问题，要花费大量的时间检查程序逻辑，一个个方法 mock 测试验证。那有人会问了，你怎么不在本地 debug 调试下呢？

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-01.gif" width="150px"/>
</div>

**你的代码本地没法启动！**

其实并不是所有的工程代码，都能本地启动运行的。尤其复杂的工程，与外部对接非常多，甚至还有一些是风险控制的问题，本地是不能启动直接调用的。也就是控制研发人员，不允许本地程序调用其他程序的接口。那么对于这样的工程，研发的自测就要通过编写 [mock](https://bugstack.cn/md/road-map/mock.html) 方式进行单元化测试。

不过这里会有一个问题，单元化的测试，mock 的数据是不会随着外部所有程序的调整动态的变更的，而是随着研发编写需求，一次写好后，后续如果这个功能没有被调整，那么 mock 测试也不会在调整了。同时还因为 mock 覆盖的场景不全，不知道引入的外部那么多接口都有哪些新增的逻辑。因而，你可能本地运行没问题，但部署到测试环境，就会有一些不缺性的报错。

对于这里的报错，当你没有 debug 手段的时候，就要把前后的报错数据，都要复制到本地，通过 mock 的方式验证程序逻辑，一点点排查。不过，这个过程也要花费好长时间，尤其是一些复杂的逻辑与外部交互又非常多的时候，调试起来很耗费时间。

所以，程序员👨🏻‍💻对于实在难以调试的代码，还有一种方式就是远程调试。把代码部署到服务器，通过请求服务器的接口，本地的 IntelliJ IDEA 打开的工程，就可以调试对应的运行数据。可以非常高效的解决 bug！

接下来，小傅哥就带着大家做一个这样的案例。如果你是一个新手小白，就更有必要学习一下这样的手段了。

> 🧧 文末还提供了17个实战项目，全套的文档、视频、代码，都可以获取。还有非常清晰的学习路线！嘎嘎冲！

## 一、测试工程

这里小傅哥为你准备好了一个测试工程，你可以直接下载验证。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-02.png" width="950px"/>
</div>

- 地址：[https://github.com/fuzhengwei/xfg-dev-tech-remote-jvm-debug](https://github.com/fuzhengwei/xfg-dev-tech-remote-jvm-debug)
- 环境：JDK 1.8、SpringBoot 2.7
- 如图，工程提供了简单的 TestApiController 一个 http 测试入口。之后通过 Dockerfie 方式构建镜像，以及提供了 docker-compose-app.yml 启动工程。重要的是 JAVA_REMOTE_DEBUG 的配置。这是一种 JavaAgent 技术，如果感兴趣可以进入小傅哥的博客，[https://bugstack.cn/](https://bugstack.cn/) 字节码编程中学习。

### 1. 测试接口

```java
@Slf4j
@RestController()
@CrossOrigin("*")
@RequestMapping("/api/v1/test/")
public class TestApiController {

    /**
     * curl --request POST \
     *   --url 'http://127.0.01:8091/xfg/api/v1/test/group_buy_notify?requestDTO=1111'
     *
     * 注意，yml 里配置了应用根目录；server.servlet.context-path: /xfg
     */
    @RequestMapping(value = "group_buy_notify", method = RequestMethod.POST)
    public String groupBuyNotify(@RequestParam String requestDTO) {
        log.info("请求参数 {}", JSON.toJSONString(requestDTO));

        return "success";
    }

}
```

- 一个简单的测试接口，访问接口地址为；`http://127.0.01:8091/xfg/api/v1/test/group_buy_notify?requestDTO=1111`
- 你可以复制 curl 部分，导入到 apipost/apifox 等工具里使用。

### 2. Dockerfile

```java
# 基础镜像
FROM openjdk:8-jre-slim

# 作者
MAINTAINER xiaofuge

# 配置
ENV PARAMS=""

# 时区
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用
ADD target/xfg-dev-tech-remote-jvm-debug-app.jar /xfg-dev-tech-remote-jvm-debug-app.jar
EXPOSE 8091 5005

ENTRYPOINT ["sh","-c","java $JAVA_REMOTE_DEBUG -jar $JAVA_OPTS /xfg-dev-tech-remote-jvm-debug-app.jar $PARAMS"]
```

- ENTRYPOINT，添加了一个 $JAVA_REMOTE_DEBUG 的动态入参，其实这个位置要填入的就是 `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005` 但并不是上线的所有程序都要做这样的事情，一般只有测试环境才需要。
- EXPOSE 8091 5005 对外暴漏应用程序所需的 8091 5005 端口。

### 3. DockerCompose 部署脚本

```java
# /usr/local/bin/docker-compose -f /docs/dev-ops/environment/environment-docker-compose-2.4.yml up -d
version: '3.8'
# docker-compose -f docker-compose-app.yml up -d
services:
  xfg-dev-tech-remote-jvm-debug-app:
    image: fuzhengwei/xfg-dev-tech-remote-jvm-debug-app:1.0
    container_name: xfg-dev-tech-remote-jvm-debug-app
    restart: on-failure
    ports:
      - "5005:5005"
      - "8091:8091"
    environment:
      - TZ=PRC
      - SERVER_PORT=8091
      # 2c4g 配置，4c8g 翻倍，-Xms4096m -Xmx4096m | -Xmx –Xms：指定java堆最大值（默认值是物理内存的1/4(<1GB)）和初始java堆最小值（默认值是物理内存的1/64(<1GB))
      - JAVA_OPTS=-Xms2048m -Xmx2048m
      - JAVA_REMOTE_DEBUG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005
    volumes:
      - ./log:/data/log
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - my-network

networks:
  my-network:
    driver: bridge
```

- 部署服务注意，要对外提供 5005、8091 两个映射端口。对于这种端口的暴漏说明，我已经提供好了基础教程，可以在这里扩展学习；[https://bugstack.cn/md/road-map/docker-what.html](https://bugstack.cn/md/road-map/docker-what.html)
- 另外在 environment 环境中，配置 `- JAVA_REMOTE_DEBUG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005` 这样就可以把远侧调试的服务给启动起来了。相当于你在自己的电脑的 IntelliJ IDEA 与服务器上的应用，通过 5005 端口进行通信完成测试debug验证。

## 二、部署程序

确保你自己本地已经安装好了 [Docker](https://www.docker.com/) Mac、Windows 电脑都可以安装。

### 1. 打包程序

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-03.png" width="650px"/>
</div>

- 通过 IntelliJ Install 打包程序。其实就是 Maven 命令，mvn clean install 的操作。


### 2. 构建镜像

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-04.png" width="650px"/>
</div>

1. mac 电脑可以点绿色箭头。
2. windows 电脑，可以通过 powershell 执行 ./build.sh

### 3. 发布项目

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-05.png" width="850px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-06.png" width="850px"/>
</div>

- mac 点击绿色箭头启动程序即可。
- windows 打开 powershell 执行脚本 `docker-compose -f docker-compose-app.yml up -d`

## 三、调试程序

### 1. IntelliJ IDEA 配置

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-07.png" width="950px"/>
</div>

- 首先，在运行调试按钮那，点击下拉框。增加一个新的调试配置。
- 之后，点击+号，添加 `Remote JVM Debug`
- 最后，填写 IP 地址和端口，点击 Apply OK 即可。

### 2. 导入接口

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-08.png" width="950px"/>
</div>

- 导入接口到 ApiPost 中调用。其他的工具也可以，这样接口可以保存起来，方便以后调试。

### 3. 远程调试

#### 3.1 启动程序

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-09.png" width="450px"/>
</div>

- 以新建的远程 debug 方式，启动程序。

#### 3.2 添加断点

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-10.png" width="750px"/>
</div>

- 添加断点。注意，这会的程序部署的要一致，不能动代码。否则和远程部署的不一致，是不能调试的。

#### 3.3 调用接口

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-11.png" width="650px"/>
</div>

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/intellij-idea-remote-jvm-debug-12.png" width="650px"/>
</div>

- 首先，在 ApiPost 中点击【发送】按钮。
- 这会，你可以在打了断点的程序中，查看到请求的调用会进来。最终执行完，远程的部署的程序也会执行完。

🌶 好啦，到这你就已经学会了远程调试了。以后自己的简历中，对于项目的描述，此类问题，你也可以讲自己是如何做的远程调试。

---

### Md Road Map Intellij Idea (`docs/md/road-map/intellij-idea.md`)

---
title: IntelliJ IDEA
lock: need
---

# IntelliJ IDEA 开发工具使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

工欲善其事必先利其器，Java 技术再牛皮，也不能用 TXT 写代码，那效率太低。而开发 Java 的工具也不少，比如；Eclipse、MyEclipse、NetBeans、JDeveloper、BlueJ、JCreator 但在众多工具中，目前高校和企业较为常用的主要是 [Intellij IDEA](https://www.jetbrains.com.cn/idea/) 系列的开发工具。

所以小傅哥本文会优先介绍 Intellij IDEA 这款 Java 开发工具，方便伙伴更好的使用开发工具编写项目。

## 一、工具安装

### 1. 下载

**下载**：[https://www.jetbrains.com.cn/idea/download/?section=mac](https://www.jetbrains.com.cn/idea/download/?section=mac) - `Windows`/`macOS(Intel/Apple Silicon)`/`Linux`

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-01.png?raw=true" width="850px"/>
</div>

- IntelliJ IDEA Ultimate 旗舰版 - 付费的，功能更多。如果需要使用可以购买或者XX。
- IntelliJ IDEA Community 社区版 - 免费的，对于大部人来说，免费的社区版就够用了。

### 2. 安装

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-02.png?raw=true" width="550px"/>
</div>

1. 无论是 Windows 还是 Mac 都是双击下载的应用程序进行安装。
2. Mac 电脑需要在弹出框后，把应用程序拖入到 Applications 中，这样就可以自动执行安装了。非常傻白甜的操作。

### 3. 主题

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-03.png?raw=true" width="550px"/>
</div>

安装完成后，打开工具会提示你有一个新的UI主题，这里你可以选择 Enable New UI 点击后软件会重新启动。新的 UI 非常简洁。

### 4. 效果

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-04.png?raw=true" width="950px"/>
</div>

这就是 IntelliJ IDEA 打开项目后的效果，分为左中右布局；四边栏为工具栏操作。
- 左；展示项目
- 中；编写代码，可以通过拖拉的方式，同时打开多个文件。这样在写代码的时候可以做个对比参考。
- 右；Maven/Gradle 数据库等操作区域，你可以托拉拽一些其他窗口到右侧。

这些功能随着你的点击使用也就逐步了解了。

## 二、常用插件

IntelliJ IDEA 除了自身的功能强大以外，还可以安装各类提效的插件。这些插件可以辅助的帮助你完成代码开发。

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-05.png?raw=true" width="950px"/>
</div>

- Jump to Line：调试代码，一步定位📌。
- Maven Helper：Maven POM 依赖，查看、分析和排除相互冲突的依赖项。简单高效。
- Statistis：代码统计插件，可以看到整个工程中你写了多少代码量。
- Sequence Diagram：用于查看你的 工程中，代码执行流程的 UML 图，可以非常方便的熟悉一些默认代码。
- FastRequest：类似于 Postman 的 IDEA 插件。它是一个强大的 restful api 工具包插件
- Coverage：单元测试覆盖率统计插件
- Squaretest：自动生成Mock测试插件
- [CodeGeeX 智能AI编程助手](https://codegeex.cn/zh-CN/downloadGuide#vscode)

此外，你也可以自己开发一些自己的 IDEA 插件，这里小傅哥写了教程[《IDEA Plugin 插件开发》](https://bugstack.cn/md/assembly/idea-plugin/2021-08-27-%E6%8A%80%E6%9C%AF%E8%B0%83%E7%A0%94%EF%BC%8CIDEA%20%E6%8F%92%E4%BB%B6%E6%80%8E%E4%B9%88%E5%BC%80%E5%8F%91%EF%BC%9F.html) vo2dto 这款用于对象转换的插件，就是小傅哥开发的。如果你有非常好用的插件，也可以在本文下修改提交。

## 三、快捷命令

- Shift 双击，搜索
- Command/Ctrl + Shift + F 文件搜搜
- Option + Command + L 格式化代码 —— 你可以格式化；整个工程、默认当前打开的文件、选中的代码区域
- Control + Option + O 排掉当前类中，不需要的引入包
- Shift + Option + 上/下 可以把当前行的代码，上移或者下移

**更多指令** Mac\Windows 有一些差别，但基本一样。

### Ctrl

| 快捷键                 | 介绍                                                         |
| :--------------------- | :----------------------------------------------------------- |
| Ctrl + F               | 在当前文件进行文本查找 `（必备）`                            |
| Ctrl + R         | 在当前文件进行文本替换 `（必备）`                            |
| Ctrl + Z         | 撤销 `（必备）`                                              |
| Ctrl + Y         | 删除光标所在行 或 删除选中的行 `（必备）`                    |
| Ctrl + X         | 剪切光标所在行 或 剪切选择内容                               |
| Ctrl + C         | 复制光标所在行 或 复制选择内容                               |
| Ctrl + D         | 复制光标所在行 或 复制选择内容，并把复制内容插入光标位置下面 `（必备）` |
| Ctrl + W         | 递进式选择代码块。可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展选中范围 `（必备）` |
| Ctrl + E         | 显示最近打开的文件记录列表 `（必备）`                        |
| Ctrl + N         | 根据输入的 **类名** 查找类文件 `（必备）`                    |
| Ctrl + G         | 在当前文件跳转到指定行处                                     |
| Ctrl + J         | 插入自定义动态代码模板 `（必备）`                            |
| Ctrl + P         | 方法参数提示显示 `（必备）`                                  |
| Ctrl + Q         | 光标所在的变量 / 类名 / 方法名等上面（也可以在提示补充的时候按），显示文档内容 |
| Ctrl + U         | 前往当前光标所在的方法的父类的方法 / 接口定义 `（必备）`     |
| Ctrl + B         | 进入光标所在的方法/变量的接口或是定义处，等效于 `Ctrl + 左键单击` `（必备）` |
| Ctrl + K         | 版本控制提交项目，需要此项目有加入到版本控制才可用           |
| Ctrl + T         | 版本控制更新项目，需要此项目有加入到版本控制才可用           |
| Ctrl + H         | 显示当前类的层次结构                                         |
| Ctrl + O         | 选择可重写的方法                                             |
| Ctrl + I         | 选择可继承的方法                                             |
| Ctrl + +         | 展开代码                                                     |
| Ctrl + -         | 折叠代码                                                     |
| Ctrl + /         | 注释光标所在行代码，会根据当前不同文件类型使用不同的注释符号 `（必备）` |
| Ctrl + [         | 移动光标到当前所在代码的花括号开始位置                       |
| Ctrl + ]         | 移动光标到当前所在代码的花括号结束位置                       |
| Ctrl + F1        | 在光标所在的错误代码处显示错误信息 `（必备）`                |
| Ctrl + F3        | 调转到所选中的词的下一个引用位置 `（必备）`                  |
| Ctrl + F4        | 关闭当前编辑文件                                             |
| Ctrl + F8        | 在 Debug 模式下，设置光标当前行为断点，如果当前已经是断点则去掉断点 |
| Ctrl + F9        | 执行 Make Project 操作                                       |
| Ctrl + F11       | 选中文件 / 文件夹，使用助记符设定 / 取消书签 `（必备）`      |
| Ctrl + F12       | 弹出当前文件结构层，可以在弹出的层上直接输入，进行筛选       |
| Ctrl + Tab       | 编辑窗口切换，如果在切换的过程又加按上delete，则是关闭对应选中的窗口 |
| Ctrl + End       | 跳到文件尾                                                   |
| Ctrl + Home      | 跳到文件头                                                   |
| Ctrl + Space     | 基础代码补全，默认在 Windows 系统上被输入法占用，需要进行修改，建议修改为 `Ctrl + 逗号` `（必备）` |
| Ctrl + Delete    | 删除光标后面的单词或是中文句 `（必备）`                      |
| Ctrl + BackSpace | 删除光标前面的单词或是中文句 `（必备）`                      |
| Ctrl + 1,2,3...9 | 定位到对应数值的书签位置 `（必备）`                          |
| Ctrl + 左键单击  | 在打开的文件标题上，弹出该文件路径 `（必备）`                |
| Ctrl + 光标定位  | 按 Ctrl 不要松开，会显示光标所在的类信息摘要                 |
| Ctrl + 左方向键  | 光标跳转到当前单词 / 中文句的左侧开头位置 `（必备）`         |
| Ctrl + 右方向键  | 光标跳转到当前单词 / 中文句的右侧开头位置 `（必备）`         |
| Ctrl + 前方向键  | 等效于鼠标滚轮向前效果 `（必备）`                            |
| Ctrl + 后方向键  | 等效于鼠标滚轮向后效果 `（必备）`                            |

### Alt

| 快捷键          | 介绍                                                         |
| :-------------- | :----------------------------------------------------------- |
| Alt + `         | 显示版本控制常用操作菜单弹出层 `（必备）`                    |
| Alt + Q         | 弹出一个提示，显示当前类的声明 / 上下文信息                  |
| Alt + F1        | 显示当前文件选择目标弹出层，弹出层中有很多目标可以进行选择 `（必备）` |
| Alt + F2        | 对于前面页面，显示各类浏览器打开目标选择弹出层               |
| Alt + F3        | 选中文本，逐个往下查找相同文本，并高亮显示                   |
| Alt + F7        | 查找光标所在的方法 / 变量 / 类被调用的地方                   |
| Alt + F8        | 在 Debug 的状态下，选中对象，弹出可输入计算表达式调试框，查看该输入内容的调试结果 |
| Alt + Home      | 定位 / 显示到当前文件的 `Navigation Bar`                     |
| Alt + Enter     | IntelliJ IDEA 根据光标所在问题，提供快速修复选择，光标放在的位置不同提示的结果也不同 `（必备）` |
| Alt + Insert    | 代码自动生成，如生成对象的 set / get 方法，构造函数，toString() 等 `（必备）` |
| Alt + 左方向键  | 切换当前已打开的窗口中的子视图，比如Debug窗口中有Output、Debugger等子视图，用此快捷键就可以在子视图中切换 `（必备）` |
| Alt + 右方向键  | 按切换当前已打开的窗口中的子视图，比如Debug窗口中有Output、Debugger等子视图，用此快捷键就可以在子视图中切换 `（必备）` |
| Alt + 前方向键  | 当前光标跳转到当前文件的前一个方法名位置 `（必备）`          |
| Alt + 后方向键  | 当前光标跳转到当前文件的后一个方法名位置 `（必备）`          |
| Alt + 1,2,3...9 | 显示对应数值的选项卡，其中 1 是 Project 用得最多 `（必备）`  |

### Shift

| 快捷键               | 介绍                                                         |
| :------------------- | :----------------------------------------------------------- |
| Shift + F1           | 如果有外部文档可以连接外部文档                               |
| Shift + F2           | 跳转到上一个高亮错误 或 警告位置                             |
| Shift + F3           | 在查找模式下，查找匹配上一个                                 |
| Shift + F4           | 对当前打开的文件，使用新Windows窗口打开，旧窗口保留          |
| Shift + F6           | 对文件 / 文件夹 重命名                                       |
| Shift + F7           | 在 Debug 模式下，智能步入。断点所在行上有多个方法调用，会弹出进入哪个方法 |
| Shift + F8           | 在 Debug 模式下，跳出，表现出来的效果跟 `F9` 一样            |
| Shift + F9           | 等效于点击工具栏的 `Debug` 按钮                              |
| Shift + F10          | 等效于点击工具栏的 `Run` 按钮                                |
| Shift + F11          | 弹出书签显示层 `（必备）`                                    |
| Shift + Tab          | 取消缩进 `（必备）`                                          |
| Shift + ESC          | 隐藏当前 或 最后一个激活的工具窗口                           |
| Shift + End          | 选中光标到当前行尾位置                                       |
| Shift + Home         | 选中光标到当前行头位置                                       |
| Shift + Enter        | 开始新一行。光标所在行下空出一行，光标定位到新行位置 `（必备）` |
| Shift + 左键单击     | 在打开的文件名上按此快捷键，可以关闭当前打开文件 `（必备）`  |
| Shift + 滚轮前后滚动 | 当前文件的横向滚动轴滚动 `（必备）`                          |

### Ctrl + Alt

| 快捷键                | 介绍                                                         |
| :-------------------- | :----------------------------------------------------------- |
| Ctrl + Alt + L        | 格式化代码，可以对当前文件和整个包目录使用 `（必备）`        |
| Ctrl + Alt + O        | 优化导入的类，可以对当前文件和整个包目录使用 `（必备）`      |
| Ctrl + Alt + I        | 光标所在行 或 选中部分进行自动代码缩进，有点类似格式化       |
| Ctrl + Alt + T        | 对选中的代码弹出环绕选项弹出层 `（必备）`                    |
| Ctrl + Alt + J        | 弹出模板选择窗口，将选定的代码加入动态模板中                 |
| Ctrl + Alt + H        | 调用层次                                                     |
| Ctrl + Alt + B        | 在某个调用的方法名上使用会跳到具体的实现处，可以跳过接口     |
| Ctrl + Alt + V        | 快速引进变量                                                 |
| Ctrl + Alt + Y        | 同步、刷新                                                   |
| Ctrl + Alt + S        | 打开 IntelliJ IDEA 系统设置 `（必备）`                       |
| Ctrl + Alt + F7       | 显示使用的地方。寻找被该类或是变量被调用的地方，用弹出框的方式找出来 |
| Ctrl + Alt + F11      | 切换全屏模式                                                 |
| Ctrl + Alt + Enter    | 光标所在行上空出一行，光标定位到新行 `（必备）`              |
| Ctrl + Alt + Home     | 弹出跟当前文件有关联的文件弹出层                             |
| Ctrl + Alt + Space    | 类名自动完成                                                 |
| Ctrl + Alt + 左方向键 | 退回到上一个操作的地方 `（必备）`                            |
| Ctrl + Alt + 右方向键 | 前进到上一个操作的地方 `（必备）`                            |
| Ctrl + Alt + 前方向键 | 在查找模式下，跳到上个查找的文件                             |
| Ctrl + Alt + 后方向键 | 在查找模式下，跳到下个查找的文件                             |

### Ctrl + Shift

| 快捷键                   | 介绍                                                         |
| :----------------------- | :----------------------------------------------------------- |
| Ctrl + Shift + F         | 根据输入内容查找整个项目 或 指定目录内文件 `（必备）`        |
| Ctrl + Shift + R         | 根据输入内容替换对应内容，范围为整个项目 或 指定目录内文件 `（必备）` |
| Ctrl + Shift + J         | 自动将下一行合并到当前行末尾 `（必备）`                      |
| Ctrl + Shift + Z         | 取消撤销 `（必备）`                                          |
| Ctrl + Shift + W         | 递进式取消选择代码块。可选中光标所在的单词或段落，连续按会在原有选中的基础上再扩展取消选中范围 `（必备）` |
| Ctrl + Shift + N         | 通过文件名定位 / 打开文件 / 目录，打开目录需要在输入的内容后面多加一个正斜杠 `（必备）` |
| Ctrl + Shift + U         | 对选中的代码进行大 / 小写轮流转换 `（必备）`                 |
| Ctrl + Shift + T         | 对当前类生成单元测试类，如果已经存在的单元测试类则可以进行选择 `（必备）` |
| Ctrl + Shift + C         | 复制当前文件磁盘路径到剪贴板 `（必备）`                      |
| Ctrl + Shift + V         | 弹出缓存的最近拷贝的内容管理器弹出层                         |
| Ctrl + Shift + E         | 显示最近修改的文件列表的弹出层                               |
| Ctrl + Shift + H         | 显示方法层次结构                                             |
| Ctrl + Shift + B         | 跳转到类型声明处 `（必备）`                                  |
| Ctrl + Shift + I         | 快速查看光标所在的方法 或 类的定义                           |
| Ctrl + Shift + A         | 查找动作 / 设置                                              |
| Ctrl + Shift + /         | 代码块注释 `（必备）`                                        |
| Ctrl + Shift + [         | 选中从光标所在位置到它的顶部中括号位置 `（必备）`            |
| Ctrl + Shift + ]         | 选中从光标所在位置到它的底部中括号位置 `（必备）`            |
| Ctrl + Shift + +         | 展开所有代码 `（必备）`                                      |
| Ctrl + Shift + -         | 折叠所有代码 `（必备）`                                      |
| Ctrl + Shift + F7        | 高亮显示所有该选中文本，按Esc高亮消失 `（必备）`             |
| Ctrl + Shift + F8        | 在 Debug 模式下，指定断点进入条件                            |
| Ctrl + Shift + F9        | 编译选中的文件 / 包 / Module                                 |
| Ctrl + Shift + F12       | 编辑器最大化 `（必备）`                                      |
| Ctrl + Shift + Space     | 智能代码提示                                                 |
| Ctrl + Shift + Enter     | 自动结束代码，行末自动添加分号 `（必备）`                    |
| Ctrl + Shift + Backspace | 退回到上次修改的地方 `（必备）`                              |
| Ctrl + Shift + 1,2,3...9 | 快速添加指定数值的书签 `（必备）`                            |
| Ctrl + Shift + 左键单击  | 把光标放在某个类变量上，按此快捷键可以直接定位到该类中 `（必备）` |
| Ctrl + Shift + 左方向键  | 在代码文件上，光标跳转到当前单词 / 中文句的左侧开头位置，同时选中该单词 / 中文句 `（必备）` |
| Ctrl + Shift + 右方向键  | 在代码文件上，光标跳转到当前单词 / 中文句的右侧开头位置，同时选中该单词 / 中文句 `（必备）` |
| Ctrl + Shift + 前方向键  | 光标放在方法名上，将方法移动到上一个方法前面，调整方法排序 `（必备）` |
| Ctrl + Shift + 后方向键  | 光标放在方法名上，将方法移动到下一个方法前面，调整方法排序 `（必备）` |

### Alt + Shift

| 快捷键                 | 介绍                                                         |
| :--------------------- | :----------------------------------------------------------- |
| Alt + Shift + N        | 选择 / 添加 task `（必备）`                                  |
| Alt + Shift + F        | 显示添加到收藏夹弹出层 / 添加到收藏夹                        |
| Alt + Shift + C        | 查看最近操作项目的变化情况列表                               |
| Alt + Shift + I        | 查看项目当前文件                                             |
| Alt + Shift + F7       | 在 Debug 模式下，下一步，进入当前方法体内，如果方法体还有方法，则会进入该内嵌的方法中，依此循环进入 |
| Alt + Shift + F9       | 弹出 `Debug` 的可选择菜单                                    |
| Alt + Shift + F10      | 弹出 `Run` 的可选择菜单                                      |
| Alt + Shift + 左键双击 | 选择被双击的单词 / 中文句，按住不放，可以同时选择其他单词 / 中文句 `（必备）` |
| Alt + Shift + 前方向键 | 移动光标所在行向上移动 `（必备）`                            |
| Alt + Shift + 后方向键 | 移动光标所在行向下移动 `（必备）`                            |

### Ctrl + Shift + Alt

| 快捷键                 | 介绍                        |
| :--------------------- | :-------------------------- |
| Ctrl + Shift + Alt + V | 无格式黏贴 `（必备）`       |
| Ctrl + Shift + Alt + N | 前往指定的变量 / 方法       |
| Ctrl + Shift + Alt + S | 打开当前项目设置 `（必备）` |
| Ctrl + Shift + Alt + C | 复制参考信息                |

### 其他

| 快捷键        | 介绍                                                         |
| :------------ | :----------------------------------------------------------- |
| F2            | 跳转到下一个高亮错误 或 警告位置 `（必备）`                  |
| F3            | 在查找模式下，定位到下一个匹配处                             |
| F4            | 编辑源 `（必备）`                                            |
| F7            | 在 Debug 模式下，进入下一步，如果当前行断点是一个方法，则进入当前方法体内，如果该方法体还有方法，则不会进入该内嵌的方法中 |
| F8            | 在 Debug 模式下，进入下一步，如果当前行断点是一个方法，则不进入当前方法体内 |
| F9            | 在 Debug 模式下，恢复程序运行，但是如果该断点下面代码还有断点则停在下一个断点上 |
| F11           | 添加书签 `（必备）`                                          |
| F12           | 回到前一个工具窗口 `（必备）`                                |
| Tab           | 缩进 `（必备）`                                              |
| ESC           | 从工具窗口进入代码文件窗口 `（必备）`                        |
| 连按两次Shift | 弹出 `Search Everywhere` 弹出层                              |

官网：[https://blog.jetbrains.com/zh-hans/idea/2022/11/intellij-idea-3/](https://blog.jetbrains.com/zh-hans/idea/2022/11/intellij-idea-3/)
其他：[https://yuzhigang.gitbooks.io/intellij-idea-tutorial/content/introduce.html](https://yuzhigang.gitbooks.io/intellij-idea-tutorial/content/introduce.html)

## 四、更多官方学习信息

<div align="center">
	<img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230701-06.png?raw=true" width="750px"/>
</div>

- IntelliJ IDEA 主要特性介绍 1：[https://www.jetbrains.com/idea/features/](https://www.jetbrains.com/idea/features/)
- IntelliJ IDEA 主要特性介绍 2：[https://www.jetbrains.com/idea/features/editions_comparison_matrix.html](https://www.jetbrains.com/idea/features/editions_comparison_matrix.html)
- 官方快速入门：[http://confluence.jetbrains.com/display/IntelliJIDEA/Quick+Start](http://confluence.jetbrains.com/display/IntelliJIDEA/Quick+Start)
- 官方在线帮助文档：[http://www.jetbrains.com/idea/webhelp/getting-help.html](http://www.jetbrains.com/idea/webhelp/getting-help.html)
- 官方 wiki：[http://wiki.jetbrains.net/intellij](http://wiki.jetbrains.net/intellij)

---

### Md Road Map Introduce (`docs/md/road-map/introduce.md`)

---
title: 小册介绍
lock: need
---

# 小傅哥 DDD 编程开发小册，帮助大家更好的落地实践

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

大家好，我是技术UP主小傅哥。

如果在面试的时候，面试官问你DDD是什么，你怎么解释？是不是感觉DDD的资料也看了不少，但好像还没有一个定义给DDD，所以炸一听这有的问题的时候，还真有点慌。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-introduce-01.jpg?raw=true" width="200px">
</div>

那DDD是什么呢？🤔

**关于DDD是什么，在维基百科有一个明确的定义。"Domain-driven design (DDD) is a major software design approach." 也就是说DDD是一种主要的软件设计方法。而软件设计涵盖了；范式、模型、框架、方法论。**

- 范式（paradigm）指的是一种编程思想。
- 模型（model）指的是对现实世界或者问题的抽象描述。
- 框架（framework）指的是提供了一系列通用功能和结构的软件工具。
- 方法论（methodology）指的是一种系统的、有组织的解决问题的方法。

所以，DDD不只是只有指导思想，伴随的DDD的还包括框架结构分层。但说到底，这些仍然是理论讨论。在没有一个DDD落地项目物参考下，其实大部分码农是没法完成DDD开发的。所以小傅哥今年花费了5个月假期/周末的时间，完成的《DDD简明开发教程》，帮助大家落地DDD编码。

>文末可以获取到基于DDD架构开发的实战项目。

## 一、能学到啥

因为DDD本身有很多的方法论，指导着框架结构的设计，从而控制着工程模块间的平衡。这种平衡的约束，起到了很好的防腐作用，天然的控制了职责的分离。不过也因为有了这些约束，很多初次上手DDD的研发伙伴不知道怎么下手了。所以以下这些内容，则是帮你进入DDD开发；

1. 为你，提供整个DDD简单版、DDD标准版，脚手架使用，并配合提供 docker compose 一键开发环境安装。这样你再使用的时候就可以更加容易进入了。
2. 为你，深度讲解DDD分层结构、DDD全模块调用链路、MVC2DDD的升级关闭和对比、DDD领域模型(账户/支付)的设计和编码。
3. 为你，拆分独立案例，讲解应用启动、配置加载、各类技术框架和分布式技术栈，在DDD分层结构下具体到每个模块中的使用手段。如；MyBatis、Dubbo、RocketMQ、Redis、Zookeeper、Sharding-JDBC、XXL-Job等。—— 这些案例都来自于业务场景中的常用使用方式，非常具有代表性。
4. 为你，讲解工程开发中常用类库和工程的测试压测处理方案。如；Guava、OKHTTP、Mock、JMeter、AB、Siege等。这些东西是为了更好的完成代码交付。
5. 为你，工程开发最后的阶段，提供；Docker、Portainer 云服务操作，以及包括对工程的全链路监控学习。此外基础的 IntelliJ IDEA、Maven、Git、Github/Gitcode/Gitee，的使用教程。

以上，这些内容的学习，可以让你既掌握DDD架构的开发使用，又能快速的学会各项基础技术栈和分布式技术栈的运用，还能学习到监控、压测、云服务操作。可以说是一举多得！嘎嘎强！

## 二、小册演示

可以这么说，这套DDD的小册课程是非常基础入门，又覆盖得极其全面。哪怕是小白研发，也能完全跟着走下来。既有文章又有视频，每一个小知识点都是一个独立的案例讲解。以下就是DDD小册内的一些截图，可以参考看下。

### 1. 工程结构模型

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/xfg-frame-archetype-04.png?raw=true" width="650px">
</div>

### 2. 架构对比参照

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ddd-02.png?raw=true" width="650px">
</div>

### 3. 模块调用链路

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-ddd-05.png?raw=true" width="950px">
</div>

### 4. 领域模型设计

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-mybatis-02.png?raw=true" width="650px">
</div>

### 5. 系统压测讲解

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-05.png?raw=true" width="650px">
</div>

### 6. 应用监控部署

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-230617-01.png?raw=true" width="850px">
</div>

>对此DDD小册感兴趣的伙伴，也可以进入小傅哥的B站进行视频学习。

## 三、小册大纲

小傅哥在初学阶段也看过网上的案例，可以说是鱼龙混杂，如果刚好自己是初学还不太懂，那么几乎要花费整个1天的时间，一遍遍百度搜索出各种有毛病的案例。才能完成自己的学习。所以基于这样的经历，小傅哥提供了完整的、前面的、成体系化的一整套学习案例。

- 工程脚手架(1)
   - DDD 脚手架

- 系统架构(5)
   - [MVC 架构](#)
   - [DDD 架构](#)
   - [MVC2DDD - 架构重构](#)
   - [DDD 架构 - 账户域](#)
   - [DDD 架构 - 交易域](#)

- 开发环境(6)
   - [IntelliJ IDEA](#)
   - [Maven](#)
   - [Git](#)
   - [Github](#)
   - [Gitcode](#)
   - [Gitee](#)

- 开发技术(11)
   - [MyBatis](#)
   - [Dubbo](#)
   - [RocketMQ](#)
   - [Quartz & XXL-Job](#)
   - [MySQL](#)
   - [db-router](#)
   - [sharding-jdbc](#)
   - [ConnectionPool](#)
   - [Zookeeper](#)
   - [Redis](#)
   - [Ignite](#)

- 常用类库(3)
   - [fastjson](#)
   - [guava](#)
   - [http](#)

- 工程测试(2)
   - [Mock](#)
   - [JMeter](#)

- 质量监控(1)
   - [skywalking 全链路监控](#)

- 发布部署(2)
   - [Docker](#)
   - [Portainer](#)

---

全小册目前发布了31节内容，分为脚手架、架构、环境、技术、类库、测试、监控、部署，8部分内容。这样整个一条龙🐲的学习，可以让大家对于技术的积累更为扎实。以后还会结合实际场景所需，扩展小册内容。如果有小伙伴需要用到的内容，不在这里，也可以提出建议或者贡献。💐

## 四、编程经验

1. 并不一定非得需要所有人一起做领域设计。一个研发有时候就够。`因为铁打的研发，流水的产品`。最熟悉系统和业务的，往往是最核心的研发。尤其是大公司变动较多的情况下，每每产品更替，都需要与研发请教整体流程。
2. DDD难落地，不是DDD有多难，是没经验的人做DDD，不清楚范式、模型、框架、方法论，只能抱着理论给团队伙伴讲，并且在很多细节使用上没法把控，导致越来越难维护。`上DDD==上一坨屎`。
3. 不是非得多复杂的系统才能用DDD，简单系统使用DDD，也会更好的维护。因为很多没彻底做过DDD的开发的，甚至并不知道domain的核心是什么，眼里只有聚合、聚合、聚合。
4. 能在MVC结构下写代码不错的人，到DDD可以写的更好。DDD只是软件设计方法的改变，但不决定原本代码垃圾的人，换个结构代码就牛逼了。
5. 不具备DDD结构设计和调整的研发，会生搬硬套DDD。所以没法根据自身业务需求调整分层的结构，如在domain领域编排复用极低的场景，可以去掉application/case层，这样会减少大量的对象转换。
6. 千万别说设计模式没用，好好看看一些高质量的框架源码，对于；分治、抽象、知识(设计原则、设计模式)的运行，是有多好。没用设计模式的DDD，就像没有家具的四居室，卧室里可以安装马桶。厨房里可以放个床。

## 五、加入学习

注意📢，DDD开发小册为小傅哥提供的免费学习资料，提供了基础内容的讲解。此外加入小傅哥【星球：码农会锁】还有DDD应用级实战项目课程，通过这些课程的实操，对实际业务场景进行架构、设计、编码、上线，更加扎实的掌握DDD领域驱动设计的运用。项目体验地址：[https://gaga.plus](https://gaga.plus) - 小傅哥为星球项目部署的演示平台。

- 【免费】- DDD开发小册；[https://bugstack.cn/md/road-map/road-map.html](https://bugstack.cn/md/road-map/road-map.html)
- 【付费】- DDD实战项目；[https://t.zsxq.com/14NGs0bGU](https://t.zsxq.com/14NGs0bGU) - `OpenAi 大模型应用`、`Lottery 分布式抽奖`、`Api网关`、`IM通信`等

>这样一套全体系的实战项目，放在一些平台售卖，至少都是几百块。但小傅哥的星球，只需要100来块钱，就可以获得几千元的学习项目！

>[🧧加入学习](https://bugstack.cn/md/zsxq/other/join.html)

小傅哥的【星球：码农会锁】，是一条龙🐲成体系的学习，因为这些内容都是小傅哥原创编写，所以学习起来的衔接性会非常强，有紧有收、循序渐进！欢迎加入，可别错过！

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/road-map-introduce-02.png?raw=true" width="750px">
</div>

---

### Md Road Map Jenkins (`docs/md/road-map/jenkins.md`)

---
title: Jenkins 发布部署
lock: need
---

# 在 Docker 中部署 Jenkins，并完成项目的构建和发布

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

<iframe id="B-Video" src="//player.bilibili.com/player.html?aid=879248890&bvid=BV1AN4y1J7R3&cid=1416090219&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="480"> </iframe>

本文的宗旨在于通过简单干净实践的方式教会读者，如何在 Docker 中部署 Jenkins，并通过 Jenkins 完成对项目的打包构建并在 Docker 容器中部署。

Jenkins 的主要作用是帮助你，把需要在本地机器完成的 Maven 构建、Docker 镜像发布、云服务器部署等系列动作全部集成在一个服务下。简化你的构建部署操作过程，因为 Jenkins 也被称为 CI&CD(持续集成&持续部署) 工具。提供超过 1000 个插件(Maven、Git、NodeJs)来支持构建、部署、自动化， 满足任何项目的需要。

官网：
- 英文：[https://www.jenkins.io/](https://www.jenkins.io/)
- 中文：[https://www.jenkins.io/zh/](https://www.jenkins.io/zh/)

本文涉及的工程：
- xfg-dev-tech-jenkins：[https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins)
- 提示：
  - 推荐使用云服务器做本节的案例 [5.5元/1个月，50元/1年](https://gaga.plus/yun.html)
  - 本节会需要用到的环境 [Docker&Portainer](https://bugstack.cn/md/road-map/docker.html)

## 一、操作说明

本节小傅哥会带着大家完成 Jenkins 环境的安装，以及以最简单的方式配置使用 Jenkins 完成对 [xfg-dev-tech-jenkins](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins) 案例项目的部署。部署后可以访问 [xfg-dev-tech-jenkins](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins) 项目提供的接口进行功能验证。整个部署操作流程如下；

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-01.png?raw=true" width="650px">
</div>

- 左侧竖列为核心配置部署流程，右侧是需要在配置过程中处理的细节。
- 通过把本地对项目打包部署的过程拆解为一个个模块，配置到 Jenkins 环境中。这就是 Jenkins 的作用。

## 二、环境配置

1. 确保你已经在(云)服务器上配置了 [Docker](https://bugstack.cn/md/road-map/docker.html) 环境，以及安装了 docker-compose。同时最好已经安装了 [Portainer](https://bugstack.cn/md/road-map/portainer.html) 管理界面这样更加方便操作。
2. 在配置和后续的验证过程中，会需要访问(云)服务的地址加端口。如果你在云服务配置的，记得开放端口；`9000 - portainer`、`9090 - jenkins`、`8091 - xfg-dev-tech-app 服务`

### 1. Jenkins 部署

#### 1.1 上传文件

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-02.png?raw=true" width="400px">
</div>

- 如图；以上配置内容已经放到 [xfg-dev-tech-jenkins](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins) 工程中，如果你是云服务器部署则需要将 dev-ops 部分全部上传到服务器的根目录下。
- compose-down.sh 是 [docker-compose](https://bugstack.cn/md/road-map/docker.html#_7-%E5%AE%89%E8%A3%85docker-compose) 下载文件，只有你安装了 docker-compose 才能执行 `docker-compose -f docker-compose-v1.0.yml up -d` 
- jdk-down.sh 是 jdk1.8 下载路径，以及解压脚本。如果你在云服务器下载较慢，也可以本地搜索 jdk1.8 下载，并上传到云服务器上解压。注意：本步骤是可选的，如果你的项目不强依赖于 jdk1.8 也可以使用 Jenkins 默认自带的 JDK17。可以通过在安装后的 Jenkins 控制台执行 `which java` 找到 JDK 路径。
- maven 下的 settings.xml 配置，默认配置了阿里云镜像文件，方便在 Jenkins 构建项目时，可以快速地拉取下载下来包。

#### 1.2 脚本说明

```shell
version: '3.8'
# 执行脚本；docker-compose -f docker-compose-v1.0.yml up -d
services:
  jenkins:
    image: jenkins/jenkins:2.439
    container_name: jenkins
    privileged: true
    user: root
    ports:
      - "9090:8080"
      - "50001:50000"
    volumes:
      - ./jenkins_home:/var/jenkins_home # 如果不配置到云服务器路径下，则可以配置 jenkins_home 会创建一个数据卷使用
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/local/bin/docker
      - ./maven/conf/settings.xml:/usr/local/maven/conf/settings.xml # 这里只提供了 maven 的 settings.xml 主要用于修改 maven 的镜像地址
      - ./jdk/jdk1.8.0_202:/usr/local/jdk1.8.0_202 # 提供了 jdk1.8，如果你需要其他版本也可以配置使用。
    environment:
      - JAVA_OPTS=-Djenkins.install.runSetupWizard=false # 禁止安装向导「如果需要密码则不要配置」docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
    restart: unless-stopped

volumes:
  jenkins_home:
```

Jenkins Docker 执行安装脚本。
- `./jenkins_home:/var/jenkins_home` 是在云服务器端挂一个映射路径，方便可以重新安装后 Jenkins 依然存在。你也可以配置为 `jenkins_home:/var/jenkins_home` 这样是自动挂在 `volumes jenkins_home` 数据卷下。
- `docker` 两个 docker 的配置是为了可以在 Jenkins 中使用 Docker 命令，这样才能在 Docker 安装的 Jenkins 容器内，使用 Docker 服务。
- `./maven/conf/settings.xml:/usr/local/maven/conf/settings.xml` 为了在 Jenkins 中使用映射的 Maven 配置。
- `./jdk/jdk1.8.0_202:/usr/local/jdk1.8.0_202` 用于在 Jenkins 中使用 jdk1.8
- `JAVA_OPTS=-Djenkins.install.runSetupWizard=false` 这个是一个禁止安装向导，配置为 false 后，则 Jenkins 不会让你设置密码，也不会一开始就安装一堆插件。如果你需要安装向导可以注释掉这个配置。并且当提示你获取密码时，你可以执行；`docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword` 获取到登录密码。

#### 1.3 执行安装

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-03.png?raw=true" width="550px">
</div>

```shell
[root@lavm-aqhgp9nber dev-ops]# docker-compose -f docker-compose-v1.0.yml up -d
[+] Building 0.0s (0/0)                                                                                                       
[+] Running 1/0
 ✔ Container jenkins  Running 
```

执行脚本 `docker-compose -f docker-compose-v1.0.yml up -d` 后，这样执行完毕后，则表明已经安装成功了💐。

### 2. 插件安装

地址：[http://localhost:9090/](http://localhost:9090/) - `登录Jenkins`

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-04.png?raw=true" width="750px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-05.png?raw=true" width="450px">
</div>

- 1~2步，设置镜像源，设置后重启一下 Jenkins。
  镜像源地址：https://mirrors.huaweicloud.com/jenkins/updates/update-center.json
- 3~4步，下载插件，先下载安装 chinese 汉化插件，方便不太熟悉 Jenkins 的伙伴更好的知道页面都是啥内容。
- 5步，所有的插件安装完成后，都需要重启才会生效。`安装完 chinese 插件，重启在进入到 Jenkins 就是汉化的页面了`
- 除了以上步骤，你还需要同样的方式安装 maven、git、docker 插件。
- 注意，因为网络问题你可以再做过程中，提示失败。没关系，你可以再搜这个插件，再重新下载。它会把失败的继续下载。

### 3. 全局工具配置

地址：[http://localhost:9090/manage/configureTools/](http://localhost:9090/manage/configureTools/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-06.png?raw=true" width="750px">
</div>

用于构建部署的 SpringBoot 应用的环境，都需要在全局工具中配置好。包括；Maven、JDK、Git、Docker。注意这里的环境路径配置，如果配置了是会提示你没有对应的路径文件夹。

### 4. 添加凭证

地址：[http://localhost:9090/manage/credentials/store/system/domain/_/](http://localhost:9090/manage/credentials/store/system/domain/_/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-07.png?raw=true" width="650px">
</div>

- 配置了Git仓库的连接凭证，才能从Git仓库拉取代码。
- 如果你还需要操作如 ssh 也需要配置凭证。

## 三、新建任务

一个任务就是一条构建发布部署项目的操作。

### 1. 配置任务

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-08.png?raw=true" width="550px">
</div>

```
xfg-dev-tech-jenkins
```

### 2. 配置Git

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-09.png?raw=true" width="550px">
</div>

```java
# 你可以 fork 这个项目，到自己的仓库进行使用
https://gitcode.net/KnowledgePlanet/ddd-scene-solution/xfg-dev-tech-content-moderation.git
```

### 3. 配置Maven

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-10.png?raw=true" width="550px">
</div>

- 在高级中设置 Maven 配置的路径 `/usr/local/maven/conf/settings.xml`。这样才能走自己配置的阿里云镜像仓库。

```shell
clean install -Dmaven.test.skip=true
```

### 3. 配置Shell

```shell
# 先删除之前的容器和镜像文件
if [ "$(docker ps -a | grep xfg-dev-tech-app)" ]; then
docker stop xfg-dev-tech-app
docker rm xfg-dev-tech-app
fi
if [ "$(docker images -q xfg-dev-tech-app)" ]; then
docker rmi xfg-dev-tech-app
fi

# 重新生成
cd /var/jenkins_home/workspace/xfg-dev-tech-jenkins/xfg-dev-tech-app
docker build -t xiaofuge/xfg-dev-tech-app .
docker run -itd -p 8091:8091 --name xfg-dev-tech-app xiaofuge/xfg-dev-tech-app
```

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-11.png?raw=true" width="550px">
</div>

- 当你熟悉后还可以活学活用，比如这里只是做build 但不做run执行操作。具体的部署可以通过 docker compose 执行部署脚本。
- 另外如果你有发布镜像的诉求，也可以在这里操作。

## 四、测试验证

### 1. 工程准备

**工程**：`https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jenkins` 你可以fork到自己的仓库进行使用，你的账号密码就是 CSDN 的账号密码。

```java
@SpringBootApplication
@RestController()
@RequestMapping("/api/")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    /**
     * http://localhost:8091/api/test
     */
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ResponseBodyEmitter test(HttpServletResponse response) {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Cache-Control", "no-cache");

        ResponseBodyEmitter emitter = new ResponseBodyEmitter();

        String[] words = new String[]{"嗨，臭宝。\r\n", "恭喜💐 ", "你的", " Jenkins ", " 部", "署", "测", "试", "成", "功", "了啦🌶！"};
        new Thread(() -> {
            for (String word : words) {
                try {
                    emitter.send(word);
                    Thread.sleep(250);
                } catch (IOException | InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

        return emitter;
    }
    
}
```

- 工程中提供了接口；`http://localhost:8091/api/test`

### 2. CI&CD - 构建发布

**地址**：[http://localhost:9090/job/xfg-dev-tech-jenkins/](http://localhost:9090/job/xfg-dev-tech-jenkins/)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-12.png?raw=true" width="850px">
</div>

- 点击构建项目，最终会完成构建和部署成功。运行到这代表你全部操作完成了。

### 3. 验证结果

**地址**：[http://localhost:9000/#!/2/docker/containers](http://localhost:9000/#!/2/docker/containers)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-13.png?raw=true" width="850px">
</div>

**访问**：[http://localhost:8091/api/test](http://localhost:8091/api/test)

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jenkins-14.png?raw=true" width="850px">
</div>

- 运行到这代表着你已经完整的走完了 Jenkins CI&CD 流程。

---

### Md Road Map Jmeter (`docs/md/road-map/jmeter.md`)

---
title: JMeter
lock: need
---

# JMeter 压测工具的配置和使用

作者：小傅哥
<br/>博客：[https://bugstack.cn](https://bugstack.cn)

> 沉淀、分享、成长，让自己和他人都能有所收获！😄

本文的宗旨在于通过简单干净实践的方式教会读者，如何使用[JMeter](https://jmeter.apache.org)进行工程的压测测试。也同时会介绍到；ApacheBench、Siege 两个更简单压测工具的使用。

压测是开发完成正式上线对外使用前非常重要的一环，尤其是各个互联网大厂，上线的核心应用和在618、双11以及各种大促时间节点下的应用，都需要进行压测摸底，知道一个系统的最大承载量，并基于这样的一个量的安全范围值内设置熔断、限流和降级的指标。—— 而且这也是面试过程中评估你是否真的做过上线系统的能力考察项；`你的系统负载量多大、部署多少台服务器、响应时间怎么样、峰值是多少`

本文涉及的工程：

- xfg-dev-tech-jmeter：[xfg-dev-tech-jmeter](https://gitcode.net/KnowledgePlanet/road-map/xfg-dev-tech-jmeter)

## 一、工具安装

这个安装分为本地安装和云服务安装，一般正规的玩法是本地安装后来写测试计划看效果。之后把jmx文件放到云服务器来执行压测。这样才能不受GUI和本地的限制，压测的比较大。**本文提供了Docker部署和执行 JMX 压测脚本**

### 1. 本地安装

- 环境：JDK 1.8+ - `因为这是一个纯Java开发的软件，所以需要JDK环境`
- 官网：[https://jmeter.apache.org/download_jmeter.cgi](https://jmeter.apache.org/download_jmeter.cgi) - `Mac 下载 apache-jmeter-5.6.2.tgz`、`Windows 下载 apache-jmeter-5.6.2.zip` 注意官网还有对应的文档，很清晰的介绍了使用方法。
- 镜像：[https://mirrors.aliyun.com/apache/jmeter/binaries/](https://mirrors.aliyun.com/apache/jmeter/binaries/) - `如果官网下载比较慢，也可以通过阿里云镜像下载`

### 2. 云服务安装

**脚本**：`xfg-dev-tech-jmeter/docs/dev-ops/docker-compose.yml`

```java
version: '3'
services:
  # JMeter是一个功能强大的性能测试工具，可以模拟多种类型的负载，并提供详细的测试报告
  # 官网：https://jmeter.apache.org/
  # 脚本：jmeter -n -t one.jmx -l one.jtl
  Jmeter:
    image: justb4/jmeter:5.5
    container_name: jmeter
    restart: always
    environment:
      - DISPLAY=:0
      - TZ=Europe/Paris
    volumes:
      - https://bugstack.cn/images/roadmap/tutorial/jmx/:/opt/apache-jmeter-5.5/jmx/
```

- 如果你本地已经安装 Docker 那么直接执行 docker-compose.yml 即可完成安装。
- 注意，`xfg-dev-tech-jmeter/docs/dev-ops/jmx` 下是 JMeter 所保存的压测脚本。

### 1. 解压启动

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-01.png?raw=true" width="550px">
</div>

进入到 apache-jmeter-5.5/bin 目录下；

- Mac 电脑，在 jmeter 上右键，选择终端启动。
- Windows 电脑，直接点 jmeter.bat 启动。

### 2. 配置语言

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-02.png?raw=true" width="550px">
</div>

修改语言有2个方式；

- 进入 apache-jmeter-5.5/bin/jmeter.properties 设置 language=zh_CN
- 如图，进入页面，手动选择。

## 二、配置说明

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-03.png?raw=true" width="550px">
</div>

这是 JMeter 压测配置中非常简单的一个**测试计划**，在这个测试计划下需要包括`线程组 - 负责运行`、`取样器(压测的接口) - 负责调接口`和`至少一个监听器 - 负责看结果`。这样才能完成压测并获得结果。

### 1. 线程组

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-04.png?raw=true" width="550px">
</div>

通过线程组开启对HTTP接口的请求循环操作方式。它可以模拟配置出流量的负载均值请求、峰值请求、逐步加量等场景。

#### 1.1 函数线程组

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-05.png?raw=true" width="750px">
</div>

- Open Mode Thread Group 支持配置简单的配置和 Groovy 脚本 如；`${__groovy((1..5).collect { "rate(" + it*10 + "/sec) random_arrivals(10 sec) pause(1 sec)" }.join(" "))}` - 请求10次，每次都递进。
- 你还可以配置这些参数；`rate(0/min) random_arrivals(10 min) rate(100/min)`、`rate(0/min) random_arrivals(5 min) rate(100/min)random_arrivals(100 min)rate(100/min) random_arrivals(5 min) rate(0/min)` - 通过这样的规律，就可以找到如何配置了。
- 此外还支持 JMeter 函数：`pause(2 min) rate(${__Random(10,50,)}/min)random_arrivals(${__Random(10,100,)} min) rate(${__Random(10,1000,)}/min)` - 也可以多行配置。
- 负载举例；总时长为1分10秒。前10秒内，速率达到10/s，然后，在1分钟内吞吐量将保持在10/s。最大吞吐量为600个/分钟。配置：`rate(0/s) random_arrivals(20 s) rate(10/s) random_arrivals(1 m) rate(10/s)`

#### 1.2 简单线程组

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-06.png?raw=true" width="750px">
</div>

简单线程组配置起来更简单，也适合一些循环压测的场景。
- 线程数：一个用户相当于一个线程。
- Ramp-Up：预期线程组的所有线程从启动-运行-释放的总时间。ramp up=0时，表示瞬时加压，启动线程的时间无限趋近于0。在负载测试的时候，尽量把ramp up设置大一些，让性能曲线平缓，容易找到瓶颈点。
- 循环次数：线程组的循环次数，如果不设置，则表示在调度时间范围内一直循环(jmeter不停的发请求)。
- 调度器：执行的时间设置。

---

此外，JMeter 还可以安装插件，设置更多的线程组模型来压测。

### 2. 取样器

JMeter 把对压测的内容，抽象为取样器。包括HTTP接口、FTP服务等。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-07.png?raw=true" width="750px">
</div>

如图你可以通过这样的方式，在创建好的线程组下，创建一个取样器(HTTP压测接口)。不过这里小傅哥更建议你使用 cURL 方式导入使用。

#### 2.1 复制 cURL

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-08.png?raw=true" width="650px">
</div>

#### 2.2 导入 cURL

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-09.png?raw=true" width="650px">
</div>

- 导入以后，可以把HTTP请求拖到线程组下面。

### 3. 监听器

线程组是各类方式的模拟压测调用，取样器HTTP是压测的接口。那么监听器就是看线程组对取样器HTTP的压测结果。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-10.png?raw=true" width="650px">
</div>

## 三、工程准备

为了让大家更加方便的测试，不用自己在折腾，可以直接使用测试工程。测试工程内提供了测试的接口，以及对应的 jmx 脚本。启动后就可以执行测试。

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-11.png?raw=true" width="750px">
</div>

- docker-compose.yml 是部署 JMeter 到 Docker 的脚本。并在脚本中映射了本地的压测脚本。
- one.jmx 是在使用 JMeter 时导出的脚本，你可以直接复制 JMeter 脚本，也可以让 JMeter 保存脚本的时候选择到这个路径下。
- 注意 one.jmx 有压测对应接口的 IP，测试的时候需要修改为你的服务器/本机IP才可以。`<stringProp name="HTTPSampler.domain">127.0.0.1</stringProp>`

## 四、压测验证

### 1. 本地压测

- 开启服务：xfg-dev-tech-jmeter
- 启动压测：JMeter

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-12.png?raw=true" width="450px">
</div>

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-13.png?raw=true" width="750px">
</div>

### 2. 脚本压测

<div align="center">
    <img src="https://bugstack.cn/images/roadmap/tutorial/roadmap-jmeter-14.png?raw=true" width="750px">
</div>

压测命令：`jmeter -n -t one.jmx -l one.jtl`

## 五、其他工具

- [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html)：一个轻量级的HTTP性能测试工具，可以模拟多种类型的负载，并提供详细的测试报告。脚本：`ab -n 10 -c 2 http://localhost:8091/api/jmeter/query_order_info?orderId=100001`
- [Siege](#)：是常用的HTTP性能测试工具，可以模拟多个并发用户发送请求。脚本：`siege -c10 -r1 -p http://localhost:8091/api/jmeter/query_order_info?orderId=100001`
- [ApiPost](https://www.apipost.cn/)：自带接口简单压测模拟，安装更加简单，适合初步压测验证。

---

--- METRICS ---
- Files Extracted: 99
- Estimated Token Budget: ~201682 tokens
- Canonical Reference: https://codewiki.google/github.com/fuzhengwei/CodeGuide
