Java微服务:别怕,这比看起来简单
\n\n您是否曾看着一个单体应用,心想:“要是能把它拆分成多个部分,这样就不用担心一个改动会破坏所有东西就好了”?恭喜您——您已经准备好迎接微服务了。在Java世界里,这个话题被各种关于难以置信的复杂性和大量技术的神话所包围。实际上,您可以从两个类和一个application.yml文件开始。
在本文中,我们不会建造一艘宇宙飞船。我们将编写两个简单的微服务,它们通过HTTP相互通信,并弄清楚真正该从哪里开始。没有魔法——只有Java、Spring Boot和常识。
\n\n什么是微服务(通俗解释)
\n\n想象一家餐厅。单体应用就像一位厨师做所有事情:煮汤、煎牛排、洗碗。微服务则像一个团队:一位厨师只负责汤品,第二位负责肉类,第三位负责甜点。每个人独立工作,但共同打造完整的菜单。
\n\n在Java中,微服务是一个独立的应用程序,负责一项业务功能(例如“用户管理”或“订单处理”)。它有自己的数据库、自己的代码,并通过网络(通常通过HTTP/REST或消息代理)与其他服务通信。
\n\n从哪里开始:必备工具
\n\n对于第一个项目,您只需要三样东西:
\n\n- \n
- Java 17+ — 具有有用功能(records、sealed classes)的现代版本。 \n
- Spring Boot 3.x — 最流行的Java微服务框架。它处理了80%的日常繁琐工作。 \n
- Maven或Gradle — 用于构建。Maven更容易上手,Gradle更快。 \n
另外,当您想增加复杂度时:
\n- \n
- Docker — 用于将服务打包到容器中。 \n
- Spring Cloud — 用于服务发现(Service Discovery)和负载均衡。 \n
- PostgreSQL/H2 — 可选的数据库。 \n
建议:不要试图立即学习Kubernetes和Kafka。从简单的REST通信开始。
\n\n编写第一个微服务:用户服务
\n\n让我们创建一个简单的微服务,能够提供用户信息。使用Spring Initializr (start.spring.io) 或手动创建项目。
\n\n在pom.xml中添加依赖:
<dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n</dependency>\n\n<dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-data-jpa</artifactId>\n</dependency>\n\n<dependency>\n <groupId>com.h2database</groupId>\n <artifactId>h2</artifactId>\n <scope>runtime</scope>\n</dependency>\n\n现在编写用户模型:
\n\nimport jakarta.persistence.*;\n\n@Entity\n@Table(name = "users")\npublic class User {\n @Id\n @GeneratedValue(strategy = GenerationType.IDENTITY)\n private Long id;\n private String name;\n private String email;\n\n // 构造函数、getter、setter(可以使用Lombok)\n public User() {}\n\n public User(String name, String email) {\n this.name = name;\n this.email = email;\n }\n\n // getter和setter\n}\n\n仓库(简化的数据访问):
\n\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface UserRepository extends JpaRepository<User, Long> {\n}\n\n以及控制器——REST端点:
\n\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\n@RequestMapping("/api/users")\npublic class UserController {\n\n private