微服务搭建
00x1 什么是微服务
微服务是一种软件架构风格,把大型应用程序拆分成多个小型、独立的服务单元,每个单元都能单独部署和维护 。百科
- 核心定义:一组小而自治的服务,每个服务专注特定业务功能,通过轻量级方式(如网络请求)互相通信 。
- 主要特点:支持独立扩展和更新,不同服务可用不同编程语言或数据库,某个服务故障不会影响整体系统 。
- 适用场景:适合业务复杂、需要快速迭代的大型系统,相比传统单体架构更灵活,但管理复杂度更高 。
- 单体架构所有的模块全都耦合在一块,代码量大,维护困难,微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。
- 单体架构所有的模块都共用一个数据库,存储方式比较单一,微服务每个模块都可以使用不同的存储方式(比如有的用redis,有的用mysql等),数据库也是单个模块对应自己的数据库。
- 单体架构所有的模块开发所使用的技术一样,微服务每个模块都可以使用不同的开发技术,开发模式更灵活。

微服务,从本质意义上看,还是 SOA 架构。但内涵有所不同,微服务并不绑定某种特殊的技术,在一个微服务的系统中,可以有 Java 编写的服务,也可以有 Python编写的服务,他们是靠Restful架构风格统一成一个系统的。所以微服务本身与具体技术实现无关,扩展性强。
- 微服务,关键其实不仅仅是微服务本身,而是系统要提供一套基础的架构,这种架构使得微服务可以独立的部署、运行、升级,不仅如此,这个系统架构还让微服务与微服务之间在结构上“松耦合”,而在功能上则表现为一个统一的整体。这种所谓的“统一的整体”表现出来的是统一风格的界面,统一的权限管理,统一的安全策略,统一的上线过程,统一的日志和审计方法,统一的调度方式,统一的访问入口等等。
- 微服务的目的是有效的拆分应用,实现敏捷开发和部署 。
- 微服务提倡的理念团队间应该是 inter-operate, not integrate 。inter-operate是定义好系统的边界和接口,在一个团队内全栈,让团队自治,原因就是因为如果团队按照这样的方式组建,将沟通的成本维持在系统内部,每个子系统就会更加内聚,彼此的依赖耦合能变弱,跨系统的沟通成本也就能降低。
应用程序的每个功能区域现在都由其自己的微服务实现。此外,Web 应用程序被拆分为一组更简单的 Web 应用程序(例如,在我们的出租车打车示例中,一个用于乘客,一个用于司机)。这使得为特定用户、设备或特殊用例部署不同的体验变得更加容易。
每个后端服务都公开一个 REST API,大多数服务使用其他服务提供的 API。例如,Driver Management 使用通知服务器来告知可用的司机有关潜在行程的信息。UI 服务调用其他服务以呈现网页。服务也可能使用异步的、基于消息的通信。本系列稍后将更详细地介绍服务间通信。
一些 REST API 也暴露给司机和乘客使用的移动应用程序。但是,这些应用程序不能直接访问后端服务。相反,通信由称为API 网关的中介进行调解。API Gateway 负责负载均衡、缓存、访问控制、API 计量和监控等任务,并且可以使用 NGINX 有效地实现API 网关。
我的理解是把每一个核心功能分开成独立的迷你单架构,通过api服务与服务之间通信。
每个核心功能都被实现为一个独立部署、独立运行的小服务(进程),服务之间通过轻量级 API(如 HTTP/REST、gRPC)进行同步或异步通信。
参考
00x2 Pig4Cloud
Pig4Cloud 是一套基于 Java 的企业级微服务快速开发平台,主要帮助开发者快速搭建后台管理系统,支持开源免费版本和商业增强版本 。
这个平台的核心目的是让开发团队少写重复代码,快速把业务系统跑起来,主要特点包括:
- 技术栈主流且新:后端基于 Spring Boot 和 Spring Cloud 构建,前端使用 Vue3、TypeScript 等现代技术,确保技术选型不落伍 。
- 架构灵活:既支持微服务架构,也支持单体架构,你可以根据项目规模自由选择,不用被架构绑死 。
- 功能模块全:内置了认证授权、多租户管理、代码生成器、工作流引擎、服务监控等常用功能,开箱即用 。
- 部署方便:支持 Docker 和 Kubernetes 容器化部署,提供了一键启动的脚本,方便在本地或服务器上快速体验 。
他有一个后端和前端
00x3 微服务结构
后端
示例,pig-3.8.2

模块定义
① pig-nacos:服务注册与发现
② pig-common: 基础依赖、jar包
③ pig-common-security:spring security模块
④ pig-auth:登录认证、token鉴权
⑤ pig-gateway: 网关
⑥ pig-upms-api: api接口定义,feign接口定义
⑦ pig-umps-biz: feign接口的实现
每一个模块结构大概如下:
以这个认证服务模块为例。

这是启动服务的代码
package com.pig4cloud.pig.auth;
import com.pig4cloud.pig.common.feign.annotation.EnablePigFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author lengleng
* @date 2018年06月21日 认证授权中心
*/
@EnablePigFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class PigAuthApplication {
public static void main(String[] args) {
//启动这个类所有的信息引用
SpringApplication.run(PigAuthApplication.class, args);
}
}
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
//new Class[]{primarySource}创建一个class类型地址的数组
return run(new Class[]{primarySource}, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
//启动服务
return (new SpringApplication(primarySources)).run(args);
}
spring运行代码
public ConfigurableApplicationContext run(String... args) {
//启动创造
Startup startup = SpringApplication.Startup.create();
//如果一个在JVM关闭时运行的钩子是ture
if (this.registerShutdownHook) {
//允许注册钩字标识打开
shutdownHook.enableShutdownHookAddition();
}
//创建引导上下文
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
//赋值
ConfigurableApplicationContext context = null;
//全局配置
this.configureHeadlessProperty();
//
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
startup.started();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), startup);
}
listeners.started(context, startup.timeTakenToStarted());
this.callRunners(context, applicationArguments);
} catch (Throwable ex) {
throw this.handleRunFailure(context, ex, listeners);
}
try {
if (context.isRunning()) {
listeners.ready(context, startup.ready());
}
//返回上下文
return context;
} catch (Throwable ex) {
throw this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
}
}
上下文
private DefaultBootstrapContext createBootstrapContext() {
//创建默认引导程序上下文
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
//把模块们的操作,装进默认上下文中
//也就是模块把操作之后的数据装进空的上下文中
this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
//返回上面操作后的上下文
return bootstrapContext;
}
主要特点
-
全局生效:一旦设置,当前 JVM 实例中的所有代码都能读取到。
-
常用于环境配置:比如指定
java.awt.headless、http.proxyHost、file.encoding等标准系统属性,也可以自定义。 -
优先级:通常在启动时通过
-D参数设置(java -Dmy.prop=value -jar app.jar),也可以在代码中用System.setProperty动态修改(会覆盖原有值)。
private void configureHeadlessProperty() {
//设定属性
//System.setProperty 是 Java 提供的一个全局设置系统属性的方法。它的作用是将一个键值对(key-value)存入整个 JVM 的系统级配置中,之后可以通过 System.getProperty(key) 在任何地方读取。
//设置键值对
// private boolean headless;
//全局配置
System.setProperty("java.awt.headless", System.getProperty("java.awt.headless", Boolean.toString(this.headless)));
}
private SpringApplicationRunListeners getRunListeners(String[] args) {
SpringFactoriesLoader.ArgumentResolver argumentResolver = ArgumentResolver.of(SpringApplication.class, this);
argumentResolver = argumentResolver.and(String[].class, args);
List<SpringApplicationRunListener> listeners = this.<SpringApplicationRunListener>getSpringFactoriesInstances(SpringApplicationRunListener.class, argumentResolver);
SpringApplicationHook hook = (SpringApplicationHook)applicationHook.get();
SpringApplicationRunListener hookListener = hook != null ? hook.getRunListener(this) : null;
if (hookListener != null) {
listeners = new ArrayList(listeners);
listeners.add(hookListener);
}
return new SpringApplicationRunListeners(logger, listeners, this.applicationStartup);
}
参考
更多推荐


所有评论(0)