在40岁老架构师尼恩的读者社群(50+)中,大量的小伙伴是架构师、高级开发,大家都有丰富的开发、架构经验。
在开发过程中,一般情况下,大家都是用现有的开发框架。
导致的一个严重问题是:很少有小伙伴能从0开始 搭建一套SpringCloud微服务脚手架(SpringCloud+ Dubbo + Docker + Jenkins)。然而,零基础 搭建一套SpringCloud微服务脚手架(SpringCloud+ Dubbo + Docker + Jenkins),这个实操对大家来说,至关重要。
尼恩一直在找一个契机,给大家梳理一个《零基础 搭建一套SpringCloud微服务脚手架》 博客。提升大家的实操能力,动手能力。
直到今天、契机终于来了。
从2020年开始,尼恩一直在写一本 微服务架构和开发领域的 至尊宝典 《SpringCloud 学习圣经》,全量的博客加起来全网阅读量在100W+。在这么大访问量的激励下,尼恩一直在对这本 《SpringCloud 学习圣经》进行迭代。
而且由于尼恩一人有精力有限,在尼恩的《技术自由圈》 高并发研究社群中,不断吸取有志之士的加入。咱们社群中一位资深的、华中科技大学硕士、有着10年开发和架构经验、并且管理一个20人团队的架构师 Andy加入了咱们技术迭代、技术研究的队伍。
他来给大家提供了一个优秀的微服务 基础架构实操案例,《零基础 搭建一套SpringCloud微服务脚手架》。
这,就是本文。当然,本文也收入了咱们的 10W字 至尊宝典 《SpringCloud alibaba 学习圣经》最新升级版, 《SpringCloud alibaba 学习圣经》宝典从此升级到了V3版本。
最新的 PDF 文档,可以到文末 公众号【技术自由圈】 获取。
微服务架构通过将复杂的单体应用拆分为一组小型、自治的服务,为构建灵活、可扩展的应用提供了一种新的方式。
微服务框架具有以下优势:
在构建微服务系统时,选择一个适合的框架可以加速开发过程并提高系统的稳定性和可维护性。
本文旨在通过手把手教程,引导读者从零开始搭建一套Java微服务框架。
我们将使用Spring Cloud作为基础框架,并结合Nacos作为服务注册中心,Spring Cloud Gateway作为API网关,以及Feign作为服务之间的通信方式。
此外,我们还将探讨如何使用Docker容器化和Jenkins进行持续集成和部署,以构建一个完整的微服务架构。
通过本文的学习,读者将掌握以下技能:
在开始构建自己的Java微服务框架之前,让我们先了解下设计微服务框架要遵守的一些基本原则。
在设计微服务框架时,我们需要遵循一些基本原则,以确保系统的可扩展性、可维护性和可靠性。以下是设计微服务框架的基本原则:
微服务架构的核心概念之一是服务的解耦和独立性。每个微服务应该具有清晰的边界,它们可以独立开发、部署和扩展。在设计框架时,要保证各个微服务之间的解耦,使其可以独立演化而不会对其他服务产生过多的影响。
微服务架构的另一个重要目标是实现可伸缩性和容错性。框架应该能够根据负载的增加或减少,自动扩展或缩减服务实例的数量。同时,要考虑到服务的容错能力,当某个服务出现故障时,框架应该能够自动将请求路由到其他可用的服务实例上。
微服务框架应该能够简化开发和部署的过程。提供一套标准化的开发模式和工具链,使开发人员可以快速构建和部署微服务。自动化的构建、测试和部署流程能够提高开发效率,减少人为错误。
框架应该具备良好的兼容性和可扩展性,能够与其他技术和组件进行集成。例如,能够无缝地与现有的数据存储、消息队列、认证授权系统等进行整合。此外,框架本身也应该是可扩展的,可以根据需求灵活地添加新的功能模块。
设计微服务框架时,需要综合考虑这些原则,并根据实际情况进行权衡和取舍。合理的框架设计能够提高开发效率、降低系统复杂度,并为微服务架构的可持续发展打下坚实的基础。在后续的章节中,我们将深入探讨如何应用这些原则,结合Spring Cloud、Nacos、Spring Cloud Gateway、Feign等组件,构建一套高效可靠的Java微服务框架。
在搭建微服务框架之前,我们需要配置一些基础设施,包括Java开发环境、构建工具、版本控制和集成开发环境(IDE)。下面是一些常用的工具和配置:
首先,确保你的系统上已经安装了Java开发工具包,Java开发环境包括Java Development Kit(JDK),它是开发和运行Java应用程序所必需的工具包。
你可以从Oracle官方网站或OpenJDK项目中下载并安装最新版本的JDK。
安装完成后,设置JAVA_HOME环境变量,指向JDK的安装目录。
D:\program\Java\jdk1.8.0_202
)。~/.bashrc或~/.bash_profile
文件,并添加以下行:export JAVA_HOME=/path/to/jdk
。然后运行source ~/.bashrc
或source ~/.bash_profile
命令使配置生效。java -version
Apache Maven是一款流行的构建工具,用于管理Java项目的依赖和构建过程。你可以从Apache Maven官方网站下载Maven,并按照官方文档的指引进行安装和配置。配置完成后,确保你可以在命令行中使用mvn命令。
Maven官方网站:https://maven.apache.org/download.cgi
C:\apache-maven-3.8.3
)。~/.bashrc或~/.bash_profile
文件,并添加以下行:export MAVEN_HOME=/path/to/maven
。然后运行source ~/.bashrc
或source ~/.bash_profile
命令使配置生效。mvn -v
Git是一款分布式版本控制系统,常用于协作开发和代码管理。你可以从Git官方网站下载并安装Git客户端。安装完成后,通过命令行验证Git是否正确安装,并设置你的用户名和邮箱。
Git官方网站:https://git-scm.com/downloads
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
git --version
推荐使用IntelliJ IDEA作为开发微服务的集成开发环境,IntelliJ IDEA是一款强大的Java集成开发环境,提供了丰富的功能和工具来开发Java应用程序。你可以从JetBrains官方网站下载并安装IntelliJ IDEA的社区版或旗舰版,一般社区版能满足基本的开发需要。安装完成后,打开IntelliJ IDEA,并根据需要进行相应的配置,例如选择主题、安装必要的插件等。
IntelliJ IDEA官方网站:https://www.jetbrains.com/idea/download/
输入名称,存储位置,jdk等信息,点击下一步
选择spring boot版本,选择所需依赖,点击创建
项目创建后,可以在pom.xml文件里继续配置依赖和构件项。
pom.xml示例如下:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.7.11version>
dependency>
<dependency>
<groupId>com.h2databasegroupId>
<artifactId>h2artifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>2021.1version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<finalName>${project.artifactId}finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
<version>3.0.1version>
<configuration>
<encoding>UTF-8encoding>
configuration>
<executions>
<execution>
<id>attach-sourcesid>
execution>
executions>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>3.0.0-M5version>
<configuration>
<parallel>methodsparallel>
<threadCount>10threadCount>
<argLine>-Dfile.encoding=UTF-8argLine>
<skipTests>trueskipTests>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-assembly-pluginartifactId>
<version>3.3.0version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependenciesdescriptorRef>
descriptorRefs>
configuration>
<executions>
<execution>
<id>make-assemblyid>
<phase>packagephase>
<goals>
<goal>singlegoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
<configuration>
<fork>truefork>
<jvmArguments>-Dfile.encoding=UTF-8jvmArguments>
<addResources>trueaddResources>
<classifier>execclassifier>
configuration>
plugin>
plugins>
build>
以上是安装和配置Java、Maven、Git和IntelliJ IDEA的详细步骤。
请按照这些步骤进行操作,确保这些工具在你的开发环境中正确安装和配置。
接下来我们就可以继续进行下一步,开始搭建Java微服务框架。
在设计微服务框架时,定义微服务接口和协议是非常重要的一步。
接下来以学生信息为例,结合JPA(Java Persistence API),提供相关的增删改查的代码示例。
JPA(Java Persistence API)是Java EE的一部分,是一种用于对象持久化的规范。
它提供了一种以面向对象的方式进行数据库操作的方式,通过简化数据库访问和数据对象之间的映射,提高了开发效率。
JPA使用注解来描述实体类和数据库表之间的映射关系,可以轻松地进行增删改查等常见数据库操作。它支持各种关系型数据库,并提供了事务管理、缓存等功能。
在我们的示例中,我们使用JPA来定义学生实体类,并通过注解来映射学生信息表的结构。这样,我们可以通过简单的代码操作来实现对学生信息的持久化和查询。
在开始之前,我们需要在项目的pom.xml文件中添加JPA的依赖。JPA是Java Persistence API的缩写,它是Java EE中持久化操作的标准规范,用于简化数据库操作和实体对象的映射关系。
请在项目的pom.xml文件中添加以下依赖:
<dependencies>
<dependency>
<groupId>javax.persistencegroupId>
<artifactId>javax.persistence-apiartifactId>
<version>2.2version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>5.6.0.Finalversion>
dependency>
<dependency>
<groupId>com.h2databasegroupId>
<artifactId>h2artifactId>
<version>1.4.200version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
dependencies>
这些依赖将启用JPA和Hibernate作为我们的持久化框架,并使用H2数据库作为示例数据库。你可以根据自己的需求替换为其他数据库。
在我们的示例中,我们将使用一个名为"student"的表来存储学生信息。该表包含三个列:id(主键),name和age。
请确保在你的数据库中创建了名为"student"的表,以及相应的列。以下是表的DDL示例:
CREATE TABLE student (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT
);
在项目中,我们需要配置application.yml文件来连接数据库和配置JPA。
请在src/main/resources目录下创建一个名为application.yml的文件,并添加以下内容:
server:
port: 8180
servlet:
context-path: /
spring:
application:
name: students-service
datasource:
url: jdbc:h2:mem:test
username: sa
password: password
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
show-sql: true
以上配置使用了H2内存数据库,并使用了默认的sa用户和password密码进行连接。同时,我们启用了Hibernate的DDL自动更新功能,并配置JPA显示SQL语句。
首先,定义一个学生实体类,用于表示学生的信息。可以包含学生的ID、姓名、年龄等属性。
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Data
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
}
使用JPA来管理学生信息的持久化操作。定义一个学生信息的持久化接口,提供增删改查等方法。
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepository extends JpaRepository<Student, Long> {
// 可以添加自定义的查询方法,如根据姓名查询学生信息等
}
在微服务框架中,通过HTTP协议暴露学生信息的API接口供外部调用。定义一个学生信息的控制器接口,提供增删改查等API方法。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/students")
public class StudentController {
@Autowired
private StudentRepository studentRepository;
@GetMapping
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
@PostMapping
public Student createStudent(@RequestBody Student student) {
return studentRepository.save(student);
}
@GetMapping("/{id}")
public Student getStudentById(@PathVariable("id") Long id) {
return studentRepository.findById(id).orElse(null);
}
@PutMapping("/{id}")
public Student updateStudent(@PathVariable("id") Long id, @RequestBody Student updatedStudent) {
Student existingStudent = studentRepository.findById(id).orElse(null);
if (existingStudent != null) {
existingStudent.setName(updatedStudent.getName());
existingStudent.setAge(updatedStudent.getAge());
return studentRepository.save(existingStudent);
}
return null;
}
@DeleteMapping("/{id}")
public void deleteStudent(@PathVariable("id") Long id) {
studentRepository.deleteById(id);
}
}
通过以上代码示例,我们定义了一个学生信息的实体类、学生信息的持久化接口和学生信息的控制器接口。
这样就可以通过API来进行学生信息的增删改查操作。
在接下来的步骤中,我们将结合Spring Cloud、Nacos、Spring Cloud Gateway、Feign、Docker和Jenkins等组件,搭建一个完整的Java微服务框架。
服务注册与发现是微服务架构中非常重要的一部分,它允许我们动态地注册和发现微服务实例,从而实现微服务之间的通信。在这一节中,我们将详细介绍服务注册与发现的工作原理和实现方式。
服务注册是指将微服务实例的信息(例如主机名、端口号、服务名称等)注册到服务注册中心,使得其他服务可以发现和调用它。下面是服务注册的步骤:
服务发现是指在需要调用其他微服务时,通过服务注册中心来获取可用的微服务实例信息。下面是服务发现的步骤:
服务注册与发现可以采用不同的实现方式,常见的有以下几种:
在实现服务注册与发现时,我们通常会使用专门的框架和工具来简化开发和管理。例如,结合Spring Cloud框架和Nacos注册中心,我们可以通过使用@EnableDiscoveryClient
注解启用服务注册与发现功能,并通过配置中心来配置服务注册中心的地址。然后,我们可以通过注入DiscoveryClient
来获取已注册的微服务实例列表,并根据需要进行调用。
通过服务注册与发现,我们可以实现微服务架构的弹性、可扩展和高可用性,使得微服务之间的通信更加灵活和可靠。
接下来,我们将使用Nacos作为服务注册与发现的中间件,并进行安装和配置。
Nacos(Naming and Configuration Service)是一个开源的服务注册与发现中间件,由阿里巴巴集团开发和维护。它提供了服务注册、发现、配置管理和动态配置更新的功能,可以帮助我们构建弹性可伸缩的微服务架构。
Nacos支持主流的服务注册和发现协议,如Eureka、Consul和Nacos自身的服务注册协议。它还提供了灵活的配置管理功能,支持动态配置刷新,可以帮助我们实现微服务的配置中心。
首先,我们需要安装Nacos Server。请按照以下步骤进行操作:
步骤 1:下载Nacos Server
你可以从Nacos的官方GitHub仓库下载最新版本的Nacos Server。
下载地址:https://github.com/alibaba/nacos/releases
步骤 2:解压Nacos Server
将下载的Nacos压缩文件解压到你选择的目录中。
步骤 3:启动Nacos Server
进入解压后的Nacos目录,执行以下命令启动Nacos Server:
PS D:\program\nacos\bin> .\startup.cmd -m standalone
"nacos is starting with standalone"
,--.
,--.'|
,--,: : | Nacos 2.2.2
,`--.'`| ' : ,---. Running in stand alone mode, All function modules
| : : | | ' ,'\ .--.--. Port: 8848
: | \ | : ,--.--. ,---. / / | / / ' Pid: 16948
| : ' '; | / \ / \. ; ,. :| : /`./ Console: http://10.23.48.43:8848/nacos/index.html
' ' ;. ;.--. .-. | / / '' | |: :| : ;_
| | | \ | \__\/: . .. ' / ' | .; : \ \ `. https://nacos.io
' : | ; .' ," .--.; |' ; :__| : | `----. \
| | '`--' / / ,. |' | '.'|\ \ / / /`--' /
' : | ; : .' \ : : `----' '--'. /
; |.' | , .-./\ \ / `--'---'
'---' `--`---' `----'
2023-05-17 11:20:55,045 INFO Tomcat initialized with port(s): 8848 (http)
Nacos Server将在默认端口(8848)启动,并以单机模式运行。
步骤 4:访问Nacos控制台
在浏览器中访问以下地址,进入Nacos控制台:
http://10.23.48.43:8848/nacos
在开始之前,我们需要在项目的pom.xml文件中添加Nacos相关依赖。请添加以下依赖:
xmlCopy code<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
<version>2021.1version>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bootstrapartifactId>
dependency>
dependencies>
以上依赖将引入Nacos服务注册与发现的功能。
现在,我们需要进行一些系统配置变更,以便我们的微服务可以与Nacos进行交互。请在bootstrap.yml文件中添加以下配置:
spring:
cloud:
nacos:
discovery:
server-addr: 10.23.48.43:8848
以上配置指定了Nacos Server的地址和端口。
接下来,我们将编写示例代码,实现服务注册与发现的功能。请添加以下代码到Spring Boot应用程序中的启动类上方:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class StudentsServiceApplication {
public static void main(String[] args) {
SpringApplication.run(StudentsServiceApplication.class, args);
}
}
在以上代码中,我们使用了@EnableDiscoveryClient注解来启用服务注册与发现功能。
现在,你的微服务将能够与Nacos进行通信,实现服务的注册和发现。
在接下来的步骤中,我们将继续编写代码来实现其他功能,如服务网关、服务间通信等。
在微服务架构中,服务之间的调用是非常常见的场景。为了简化服务调用的过程并实现负载均衡,我们可以使用Feign与Nacos结合来实现。本节将详细介绍服务调用的概念以及如何使用Feign与Nacos来实现服务调用和负载均衡。
服务调用是指一个微服务向另一个微服务发起请求,获取所需的数据或执行特定的操作。在微服务架构中,服务调用可以跨越多个微服务实例,因此需要一种机制来管理和处理服务之间的通信。
下面是使用Feign与Nacos结合实现服务调用和负载均衡的步骤:
在项目的pom.xml文件中添加Feign相关的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-loadbalancerartifactId>
dependency>
dependencies>
在启动类上添加@EnableFeignClients
注解,启用Feign客户端:
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class StudentsServiceApplication {
public static void main(String[] args) {
SpringApplication.run(StudentsServiceApplication.class, args);
}
}
创建一个Feign客户端接口,使用@FeignClient
注解指定要调用的微服务名称和相关配置:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "students-service")
public interface StudentFeignClient {
@GetMapping("/students/{id}")
Student getStudentById(@PathVariable("id") Long id);
}
通过注入Feign客户端接口,并调用相应的方法来进行服务调用:
import com.crazymaker.students.entity.Student;
import com.crazymaker.students.feign.StudentFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StudentService {
private StudentFeignClient feignClient;
@Autowired
public StudentService(StudentFeignClient feignClient) {
this.feignClient = feignClient;
}
public Student getStudentById(Long id) {
return feignClient.getStudentById(id);
}
}
在上面的示例中,通过serviceClient.getStudentById()
来调用目标微服务的接口。
通过以上步骤,我们可以使用Feign与Nacos结合来实现服务调用和负载均衡。Feign将负责处理底层的HTTP通信细节,而Nacos将负责维护微服务实例列表和选择合适的实例进行调用,从而实现了服务调用和负载均衡的功能。
服务监控是指对微服务架构中的各个服务进行实时监控和管理,以确保系统的稳定性和可靠性。通过监控服务的运行状态、性能指标和异常情况,可以及时发现问题并采取相应措施,以提高系统的可用性和响应能力。
日志管理是指对微服务架构中生成的日志进行收集、存储、分析和展示的过程。日志是系统运行的重要记录,通过对日志进行管理和分析,可以了解系统的运行状况、故障信息和异常情况,以便于问题排查和系统优化。
服务监控和日志管理对于微服务架构具有重要的必要性和优势:
下面我们通过分别搭建和配置Spring Boot Admin 和 ELK 服务来实现性能监控和日志管理:
Spring Boot Admin是一个开源的服务监控和管理工具,它提供了一个Web界面,用于监控和管理基于Spring Boot的应用程序。通过Spring Boot Admin,可以实时监控和管理应用程序的运行状态、健康状况、性能指标等,并提供了强大的可视化和告警功能。
安装和配置Spring Boot Admin的步骤如下:
按上文步骤新建一个Spring Boot项目, 添加Spring Boot Admin的依赖
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>3.0.3version>
dependency>
bootstrap.yml
和application.yml
文件spring:
cloud:
nacos:
discovery:
server-addr: 10.23.48.43:8848
server:
port: 8181
servlet:
context-path: /
spring:
application:
name: admin-service
@EnableDiscoveryClient
@SpringBootApplication
@EnableAdminServer
public class AdminServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AdminServiceApplication.class, args);
}
}
启动应用程序, 点击 http://10.23.48.43:8181/applications 访问监控页面
1)pom.xml 里添加admin依赖
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>3.0.3version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
2)在Spring Boot应用程序的配置文件(如application.yml)中,配置Spring Boot Admin Server的相关信息:
spring:
boot:
admin:
client:
url: http://10.23.48.43:8181 # Spring Boot Admin Server的地址
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
重新启动应用程序, 它将自动注册到Spring Boot Admin Server。
通过以上配置,我们可以实现Spring Boot Admin与Nacos的结合,使得应用程序能够通过Spring Boot Admin进行监控和管理。
ELK是一个流行的日志管理和分析解决方案,由Elasticsearch、Logstash和Kibana三个项目组成,常用于日志收集和分析。
日志主要包括系统日志、应用程序日志和安全日志。运维和开发人员可以通过日志了解服务器运行过程中发生的错误及错误产生的原因。定期分析日志可以了解服务器的运行情况、性能、安全性等。
每台服务器或应用程序都会产生日志,如果每次都登录这些服务器查看日志并分析会耗费大量时间,而且效率低下,这时我们就需要思考如何将日志汇总起来统一查看。日志集中管理之后又会产生新的问题,日志量太大,日志统计和检索又成为新的问题,如何能实现高性能的检索统计呢?ELK能完美解决我们的问题。
关于ELK的原理和实操,强烈推荐:
ELK日志平台(elasticsearch +logstash+kibana)原理和实操(史上最全):
https://www.cnblogs.com/crazymakercircle/p/16732034.html
本文这里为了方便演示,仅演示利用docker容器在本机部署ELK,在实际生产环境下,推荐使用多台linux服务器,安装ELK集群。
首先新建elk目录,在目录下新建相关文件夹:
docker-compose.yml内容如下:
version: '3.2'
services:
elasticsearch:
image: elasticsearch:7.17.4
volumes:
- ./es/plugins:/usr/share/elasticsearch/plugins #插件文件挂载
- ./es/data:/usr/share/elasticsearch/data #数据文件挂载
- ./es/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml #配置
ports:
- '9200:9200'
- '9300:9300'
container_name: elasticsearch
environment:
- 'cluster.name=elasticsearch' #设置集群名称为elasticsearch
- 'discovery.type=single-node' #以单一节点模式启动
- 'ES_JAVA_OPTS=-Xms1024m -Xmx1024m' #设置使用jvm内存大小
networks:
- elk
logstash:
image: logstash:7.17.4
container_name: logstash
volumes:
- './logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf'
ports:
- '5044:5044'
- '50000:50000/tcp'
- '50000:5000/udp'
- '9600:9600'
environment:
LS_JAVA_OPTS: -Xms1024m -Xmx1024m
TZ: Asia/Shanghai
MONITORING_ENABLED: false
links:
- elasticsearch:es #可以用es这个域名访问elasticsearch服务
networks:
- elk
depends_on:
- elasticsearch
kibana:
image: kibana:7.17.4
container_name: kibana
volumes:
- ./kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
ports:
- '5601:5601'
links:
- elasticsearch:es #可以用es这个域名访问elasticsearch服务
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200 #设置访问elasticsearch的地址
- 'elasticsearch.hosts=http://es:9200' #设置访问elasticsearch的地址
- I18N_LOCALE=zh-CN
networks:
- elk
depends_on:
- elasticsearch
networks:
elk:
name: elk
driver:
bridge
在es目录下新建 data、plugins 文件夹, 以及elasticsearch.yml文件,内容如下:
cluster.name: elasticsearch # 集群名称
node.name: node-1 # 节点名称
network.host: 0.0.0.0 # 监听地址
http.port: 9200 # 监听端口
http.cors.enabled: true
http.cors.allow-origin: "*"
在logstash目录下新建logstash.conf文件, 内容如下:
input {
tcp {
port => 5000
codec => json
}
}
filter {
# 进行过滤和转换规则的配置
}
output {
elasticsearch {
hosts => ["es:9200"] # Elasticsearch的地址
index => "my-application-%{+YYYY.MM.dd}" # 索引名称,可按日期划分
}
}
在kibana目录下,创建config文件夹,并新建kibana.yml文件,内容如下:
# Default Kibana configuration for docker target
server.host: '0.0.0.0'
server.shutdownTimeout: '5s'
elasticsearch.hosts: ['http://elasticsearch:9200']
monitoring.ui.container.elasticsearch.enabled: true
server.port: 5601 # 监听端口
启动:
docker-compose -f docker-compose.yml up -d
logback-spring.xml
:<configuration>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>10.23.48.43:5000destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
appender>
<root level="info">
<appender-ref ref="logstash" />
root>
configuration>
<dependency>
<groupId>net.logstash.logbackgroupId>
<artifactId>logstash-logback-encoderartifactId>
<version>7.2version>
dependency>
通过以上步骤,我们可以搭建起ELK Stack,并将应用系统接入到ELK Stack中进行日志的收集、存储、分析和可视化展示。这样,我们可以方便地对日志进行搜索、过滤、聚合和可视化,帮助我们快速定位问题、监控系统的运行状况,并提供数据支持进行性能优化和故障排查。
通过结合这些开源中间件,我们可以实现对微服务的全面监控和日志管理,帮助我们及时发现问题、优化性能,并提供可视化的展示和分析工具,从而提升微服务架构的可靠性和稳定性。
在微服务架构中,服务安全保护是至关重要的,它们可以保护微服务免受未经授权的访问,并确保只有经过身份验证和授权的用户才能访问受保护的资源。
Spring Cloud Gateway是一个基于Spring Framework 5、Project Reactor和Spring Boot 2构建的轻量级网关服务,用于构建和管理微服务架构中的API网关。
API网关在微服务架构中安全方面扮演着重要的角色,它作为系统的入口,它可以提供以下安全功能:
访问控制:API网关可以对传入的请求进行访问控制,确保只有经过身份验证和授权的用户能够访问受保护的资源。它可以验证请求中的身份验证令牌或证书,并根据配置的权限规则进行访问控制。
安全认证和授权:API网关可以与认证和授权中间件(如OAuth2)集成,实现对微服务的安全认证和授权。它可以验证请求中的访问令牌,并将认证和授权信息传递给后端的微服务,以确保只有具有足够权限的用户能够访问特定的资源。
保护后端服务:API网关可以隐藏后端的微服务架构,只暴露必要的接口给外部客户端,从而降低了被恶意攻击的风险。它可以阻止未经授权的请求直接访问后端服务,并提供请求的限流和缓冲功能,以保护后端服务免受过载或恶意攻击。
安全审计和日志记录:API网关可以记录请求和响应的详细信息,包括访问时间、来源IP、请求内容等,以便进行安全审计和故障排查。它可以将日志记录到集中的日志管理系统中,方便监控和分析。
攻击防护:API网关可以实施一些安全防护措施,如防止跨站脚本攻击(XSS)、跨站请求伪造(CSRF)和注入攻击等。它可以对传入的请求进行验证和过滤,以识别和阻止潜在的恶意行为。
综上所述,API网关在安全方面具有重要的作用。它可以提供访问控制、安全认证和授权、保护后端服务、安全审计和日志记录以及攻击防护等功能,帮助确保微服务架构的安全性和可靠性。
通过合理配置和使用适当的安全机制,API网关可以成为微服务架构中的首道防线,保护系统免受潜在的安全威胁。
下面是搭建和配置Spring Cloud Gateway的步骤示例:
首先创建一个Spring Boot应用, 在项目的pom.xml
文件中添加相应的依赖配置。
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
dependencies>
接下来,在application.yml
文件中配置Spring Cloud Gateway和Nacos的相关信息。
# Spring Cloud Gateway配置
server:
port: 8182
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
# Nacos配置
spring:
cloud:
nacos:
discovery:
server-addr: ${nacos.server-addr} # Nacos Server地址
# 网关路由配置
spring:
cloud:
gateway:
routes:
- id: sample-service # 路由ID
uri: lb://student-service # 后端服务名
predicates:
- Path=/student/** # 匹配的路径
filters:
- StripPrefix=1 # 去除前缀
以上配置中,需要将nacos.server-addr
替换为实际的Nacos Server地址。
然后,创建一个启动类并添加@EnableDiscoveryClient
注解,启用服务发现功能。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
最后,通过配置路由规则,将请求转发到后端的微服务。可以使用@Bean
注解在配置类中定义路由规则,或者使用配置文件中的spring.cloud.gateway.routes
属性进行配置。
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("student-service", r -> r.path("/student/**")
.uri("lb://student-service"))
.build();
}
}
通过以上配置,Spring Cloud Gateway将根据路由规则将/sample/**
路径的请求转发到名为sample-service
的后端微服务。
请注意,示例中的sample-service
是一个示意的后端微服务名称,需要根据实际情况替换为真实的微服务名称。
这样,结合Spring Cloud Gateway和Nacos的示例就完成了。启动应用后,它将根据配置的路由规则将请求转发到相应的后端微服务,并通过Nacos进行服务的注册和发现。
Spring Cloud Gateway作为微服务架构的入口,除了提供了路由转发,还提供了负载均衡、过滤器、安全认证、请求限流和监控等功能,
关于服务保护,本圣经后面有专栏介绍。当然,有兴趣的小伙伴可以阅读
SpringCloud gateway (史上最全) - 疯狂创客圈:https://www.cnblogs.com/crazymakercircle/p/11704077.html
进一步学习和掌握相关知识。
持续集成(Continuous Integration)是一种软件开发实践,旨在频繁地将代码集成到主干版本控制系统中。持续部署(Continuous Deployment)是持续集成的延伸,自动将通过持续集成构建的可部署软件包发布到生产环境。
以下是一种基本的实现方式:
接下来,我们将分别介绍Jenkins和Docker,然后提供详细的配置步骤来实现持续集成和部署。
Jenkins是一个开源的持续集成工具,它提供了一系列功能和插件,用于自动化构建、测试和部署软件。以下是Jenkins的基本概念和特点:
Docker是一个开源的容器化平台,它可以将应用程序及其依赖项打包到容器中,提供了一致、可重复和可移植的部署环境。以下是Docker的基本概念和特点:
隔离的,拥有自己的文件系统、进程空间和网络接口。
FROM openjdk:8-jre
RUN mkdir /app
COPY students-service-exec.jar /app/app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"]
EXPOSE 8180
安装过程可参考 https://zhuanlan.zhihu.com/p/566398364
构建成功后,我们可以在docker桌面端看到students-service
服务已启动,
通过以上步骤,您可以使用Jenkins和Docker实现持续集成和部署。
Jenkins将根据配置的触发器自动执行构建任务,通过Docker构建和发布镜像,实现持续集成和部署的流程。
您可以根据具体的项目需求和环境配置Jenkins任务和Docker构建脚本,以实现自动化的软件交付流程。
在本文中,我们首先讨论了微服务框架的基本原则,然后通过安装和配置Java、Maven、Git和IDEA等工具,为搭建基础设施做好准备。接着,我们定义了微服务接口和协议,并使用JPA提供了增删改查的代码示例。通过集成Nacos,我们实现了服务注册与发现,以及使用Feign实现服务调用和负载均衡。
我们还介绍了Spring Boot Admin和Elasticsearch,用于实现服务监控和日志管理。最后,我们使用Spring Cloud Gateway实现了服务安全保护,并通过Jenkins和Docker实现了持续集成和部署。
通过这个搭建过程,我们达到了构建一个完整的Java微服务框架的目标。
我们建立了基础设施,定义了接口和协议,实现了服务注册与发现、服务调用和负载均衡、服务监控和日志管理、服务安全和认证授权,并实现了持续集成和部署。
搭建过程存在的不足和改进的方向如下:
通过上述改进,我们可以进一步提升微服务框架的性能监控、报警能力,以及部署和管理的效率和可靠性。这将有助于更好地满足不断变化的业务需求,并提升系统的可靠性和稳定性。
《吃透8图1模板,人人可以做架构》
《10Wqps评论中台,如何架构?B站是这么做的!!!》
《阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了》
《峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?》
《100亿级订单怎么调度,来一个大厂的极品方案》
《2个大厂 100亿级 超大流量 红包 架构方案》
… 更多架构文章,正在添加中
《响应式圣经:10W字,实现Spring响应式编程自由》
这是老版本 《Flux、Mono、Reactor 实战(史上最全)》
《Spring cloud Alibaba 学习圣经》
《分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)》
《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)》
《Linux命令大全:2W多字,一次实现Linux自由》
《TCP协议详解 (史上最全)》
《网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!》
《Redis分布式锁(图解 - 秒懂 - 史上最全)》
《Zookeeper 分布式锁 - 图解 - 秒懂》
《队列之王: Disruptor 原理、架构、源码 一文穿透》
《缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)》
《缓存之王:Caffeine 的使用(史上最全)》
《Java Agent 探针、字节码增强 ByteBuddy(史上最全)》
4000页《尼恩Java面试宝典 》 40个专题
以上尼恩 架构笔记、面试题 的PDF文件更新,▼请到下面【技术自由圈】公号取 ▼