微服务构建: Spring Boot

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:  在展开 Spring Cloud 的微服务架构部署之前, 我们先了解一下用于构建微服务的基础框架-Spring Boot。

 在展开 Spring Cloud 的微服务架构部署之前, 我们先了解一下用于构建微服务的基础框架-Spring Boot。 由于 Spring Cloud 的构建基于 Spring Boot 实现, 在后续的示例中我 们将大量使用 Spring Boot 来构建微服务架构中的基础设施以及一些试验中使用的微服务。 为了能够辅助后续内容的介绍,确保读者有一定的Spring Boot基础,在这里先对Spring Boot 做一个简单的介绍, 以保证读者能够有一定的基础去理解后续介绍的内容并顺利完成后续 的一些示例试验。

       在这里介绍 Spring Boot 的目的除了它是 Spring Cloud 的基础之外, 也由于其自身的各 项优点, 如自动化配置、 快速开发、 轻松部署等, 非常适合用作微服务架构中各项具体微 服务的开发框架。所以我们强烈推荐使用 Spring Boot 来构建微服务, 它不仅可以帮助我们 快速地构建微服务, 还可以轻松简单地整合 Spring Cloud 实现系统服务化, 而如果使用了 传统的 Spring 构建方式的话, 在整合过程中我们还需要做更多的依赖管理工作才能让它们 完好地运行起来。

       在本文中我们将介绍下面这些与后续介绍有密切联系的内容: 

               • 如何构建 Spring Boot 项目 

               • 如何实现 RESTfulAPI 接口 

               • 如何实现多环境的 Spring Boot 应用配置 

               • 深入理解 Spring Boot 配置的启动机制

               • Spring Boot 应用的监控与管理

1、框架介绍

    对于很多Spring框架的初学者来说, 经常会因为其繁杂的配置文件而却步。 而对于很 多老手来说, 每次新构建项目总是会重复复制粘贴一 些差不多的配置文件这样枯燥乏味的事。

   Spring Boot的出现 可以有效改善这类问题,SpringBoot的宗旨并非要重写Spring或是 替代Spring, 而是希望通过设计大量的自动化配置等方式来简化Spring原有样板化的配置, 使得开发者可以快速构建应用。 

    除了解决配置问题之外, Spring Boot还通过一系列StaiterPOMs的定义, 让我们整合 各项功能的时候, 不需要在 Maven的pom.xml中维护那些错综复杂的依赖关系, 而是通 过类似模块化的Starter模块定义来引用, 使得依赖管理工作变得更为简单。

     在如今容器化大行其道的时代,Spring Boot除了可以很好融入Docker之外, 其自身就 支持嵌入式的 Tomcat、 Jetty 等容器。 所以, 通过Spring Boot 构建的应用不再需要安装 Tomcat, 将应用打包成war, 再部署到Tomcat 这样复杂的构建与部署动作, 只需将Spring Boot应用打成jar包, 并通过java -jar命令直接运行就能启动一个标准化的Web应用, 这使得Spring Boot应用变得非常轻便。

2、快速搭建SpringBoot项目

   在本文中, 我们将逐步指引读者创建一个Spring Boot的基础项目, 并且实现 一个简单 的RESTfulAPL 通过这个例子对Spring Boot有一个初步的了解, 并体验其结构简单、 开 发迅速的特性。

   项目构建与解析

         系统及工具版本要求 

                • Java 7及以上版本 

                • Spring Framework 4.2.7及以上版本 

                • Maven 3.2及以上版本/Gradle 1.12及以上版本 

        本文内容均采用Java 1.7、 Spring Boot 1.5.10调试通过。

https://img1.mukewang.com/5b28a12b0001ae2113220976.jpg

工程结构解析

• src/main/java: 主程序入口 DmsApplication, 可以通过直接运行该类来 启动Spring Boot应用。

• src/main/resources: 配置目录, 该目录用来存放应用的一些配置信息, 比如 应用名、服务端口、数据库链接等。由千我们引入了Web模块,因此产生了static 目录与templates目录, 前者用于存放静态资源, 如图片、 css、JavaScript等; 后者用千存放Web页面的模板文件, 这里我们主要演示提供RESTful APL所以这 两个目录并不会用到。 

• src/test/: 单元测试目录, 生成的DmsApplicationTests通过JUnit 4实 现, 可以直接用运行Spring Boot应用的测试。 后文中, 我们会演示如何在该类中测 试RESTfulAPI。

    Maven配置分析 打开当前工程下的pom.xml文件, 看看生成的项目都引入了哪些依赖来构建Spring Boot工程, 内容大致如下所示。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=" 

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  

<modelVersion>4.0.0</modelVersion

<groupId>com.baihe.dms</groupId>   

<artifactId>dms</artifactId>   

<version>1.0</version

<packaging>jar</packaging

<name>dms</name>   

<description>Deduct Money System</description>   

<parent>     

<groupId>org.springframework.boot</groupId>    

<artifactId>spring-boot-starter-parent</artifactId>    

<version>1.5.10.RELEASE</version>      

<relativePath/> <!-- lookup parent from repository -->    </parent>

<properties>     

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>     

<java.version>1.7</java.version>   

</properties>

<dependencies>       

<dependency>         

<groupId>log4j</groupId>           

<artifactId>log4j</artifactId>         

<version>1.2.17</version>      

</dependency>    

<dependency>         

<groupId>org.springframework.boot</groupId>        

<artifactId>spring-boot-starter-aop</artifactId>       

</dependency>    

<dependency>         

<groupId>org.springframework.boot</groupId>        

<artifactId>spring-boot-starter-web</artifactId>       

</dependency>    

<dependency>         

<groupId>org.mybatis.spring.boot</groupId>         

<artifactId>mybatis-spring-boot-starter</artifactId>           

<version>1.3.1</version>       

</dependency>    

<dependency>         

<groupId>org.springframework.boot</groupId>        

<artifactId>spring-boot-starter-actuator</artifactId>      

</dependency>    

<dependency>         

<groupId>org.springframework.boot</groupId>        

<artifactId>spring-boot-starter-test</artifactId>          

<scope>test</scope>    

</dependency>    

<dependency>         

<groupId>com.alibaba</groupId>         

<artifactId>druid</artifactId>         

<version>1.1.7</version>       

</dependency>    

<dependency>         

<groupId>mysql</groupId>           

<artifactId>mysql-connector-java</artifactId>          

<scope>runtime</scope>     

</dependency>        

<dependency>           

<groupId>com.alibaba</groupId>            

<artifactId>fastjson</artifactId>            

<version>1.2.14</version>        

</dependency>        

<dependency>         

<groupId>commons-httpclient</groupId>          

<artifactId>commons-httpclient</artifactId>       

 <version>3.1</version>       

 </dependency>      

 <dependency>           

 <groupId>dom4j</groupId>         

 <artifactId>dom4j</artifactId>           

 <version>1.6.1</version>     

 </dependency>        

 <dependency>            

 <groupId>jaxen</groupId>            

 <artifactId>jaxen</artifactId>            

 <version>1.1.6</version>        

 </dependency>        

 <dependency>           

<groupId>org.apache.httpcomponents</groupId>            

<artifactId>httpclient</artifactId>            

<version>4.5.5</version>       

 </dependency>         

 <dependency>            

 <groupId>net.minidev</groupId>            

 <artifactId>json-smart</artifactId>          

 <version>1.2</version>       

 </dependency>  

 </dependencies>

 <build>    

 <plugins>          

 <plugin>               

 <groupId>org.springframework.boot</groupId>              

 <artifactId>spring-boot-maven-plugin</artifactId>        

 </plugin>      

 </plugins

 </build>

 </project>

   在基础信息部分, groupid和 artifactId 对应生成项目时页面上输入的内容。 另 外, 我们还可以注意到, 打包形式为 jar, 正如我们 之前所介绍的,Spring Boot默认将该Web应用打包为jar 的形式, 而非war 的形式, 因为 默认 的Web模块依赖 会包含嵌入式的Tomcat , 这样使得我们的应用jar自身就具备了提供 Web服务的能力, 后续我们会演示如何启动它。 

    父项目parent配置指定为 spring-boot-starter-parent的1. 5.10 版本, 该父项 目中定义了Spring Boot版本的基础依赖以及 一 些默认配置内容 , 比如,配置文件application.properties的位置等。 在项目依赖 dependencies配置中, 包含了下面两项。 

          • spring-boot-starter-web: 全栈Web开发模块, 包含嵌入式Tomcat、 Spring MVC。 

          • spring-boot-starter-test: 通用测试模块, 包含JUnit、 Hamcrest、 Mockito 。 

    这里所引用的web和test 模块,在SpringBoot 生态中被称为Starter POMs。Starter POMs 是一系列轻便的依赖 包, 是一套一站式的Spring相关技术的解决方案。 开发者在使用和整 合模块时, 不必再去搜寻样例代码中的依赖配置来复制使用, 只需要引入对应的模块包即 可 。 

    比如, 开发Web应用的时候, 就引入spring-boot-starter-web, 希望应用具备 访问数据库能力的时候, 那就再引入 spring-boot-starter-jdbc 或是更好用的 spring-boot-starter-data-jpa。 在使用SpringBoot构建应用的时候, 各项功能模 块的整合不再像传统Spring应用的开发方式那样,需要在 pom.xml中做大量的依赖配置, 而是通过使用StarterPOMs定义的依赖包,使得功能模块整合变得非常轻巧, 易于理解与使用。 

3、实现RESTfulAPI

   在Spring Boot中创建一个RESTfulAPI的实现代码同SpringMVC应用一样, 只是不 需要像SpringMVC那样先做很多配置, 而是像下面这样直接开始编写Controller内容:

• 新建package, 命名为com.baihe.dms.controller.CmsController, 可根据实际的构建情况修改成自 己的路径。

 • 新建CmsController类,内容如下所示。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

package com.baihe.dms.controller;

import com.baihe.dms.entity.common.CmsException;

import com.baihe.dms.entity.common.ResponseData;

import com.baihe.dms.service.WithholdService;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

 

@Controller("cmsController")

@RequestMapping(value = "/")

public class CmsController {    

      private Logger logger = Logger.getLogger(this.getClass());    

      private WithholdService withholdService;    

      CmsController(@Autowired  WithholdService withholdService) 

      {       

           this.withholdService = withholdService;   

       }    

       @RequestMapping(value = "/withhold" , method =  RequestMethod.POST)    

       @ResponseBody   

       public ResponseData withhold(String contractNo, Long requestNo, 

         Long userId,Long projectId,Integer planStep, String bankCode, 

         Double totalAmount,Integer overdueFlag,Integer incomeFree) {        

            try {            

              return withholdService.withhold(contractNo, requestNo, userId, 

              projectId, planStep, bankCode, totalAmount, overdueFlag, incomeFree);

            catch (CmsException e) {

              return ResponseData.no(e.getErrCode());

            catch (Exception e) {            

                logger.debug("withhold", e);            

                return ResponseData.no(ResponseData.INTERNAL_ERROR);

            }    

      }

 }

ResponseData类:

package com.baihe.dms.entity.common;

import java.io.Serializable;

/**

 * 接口返回的数据

 */

public class ResponseData implements Serializable {

    private static final long serialVersionUID = 2047667816784695690L;

    public static final int OK = 200; // 非 OK 的都是失败

    public static final int NO = -1;

    public static final int INTERNAL_ERROR = -99;

    public static final int INVALID_PARAMETER = -100;

    public static final int NULL_PARAMETER = -101;

    public static final int INVALID_AMOUNT = -102;

    public static final int INVALID_BANKCODE = -103;

    public static final int HAS_UNFINISHED_REQUEST = -104;

    public static final int INVALID_SPLIT_CONFIG = -105;

    public static final int SPLIT_TOO_MANY = -106;

    public static final int NOT_NEED_SPLIT = -107;

    private Integer code = NO;

    private String message = "";

    private Object data;

    public Integer getCode() {

        return code;

    }

    public void setCode(Integer code) {

        this.code = code;

    }

    public Object getData() {

        return data;

    }

    public void setData(Object data) {

        this.data = data;

    }

    public String getMessage() {

        return message;

    }

    public void setMessage(String message) {

        this.message = message;

    }

    private void generateMessage(int errCode) {

        String message = "未知错误";

        switch (errCode) {

            case INTERNAL_ERROR:

                message = "内部错误";

                break;

            case INVALID_PARAMETER:

                message = "无效的参数";

                break;

            case NULL_PARAMETER:

                message = "参数不能为空";

                break;

            case INVALID_AMOUNT:

                message = "无效的金额";

                break;

            case INVALID_BANKCODE:

                message = "无效的银行编码";

                break;

            case HAS_UNFINISHED_REQUEST:

                message = "用户尚有未完成的交易";

                break;

            case INVALID_SPLIT_CONFIG:

                message = "拆分配置无效";

                break;

            case SPLIT_TOO_MANY:

                message = "拆分数目过多";

                break;          

            case NOT_NEED_SPLIT:

                message = "金额没有变化,无需拆分";

                break;

            case NO:

                message = "内部错误";

                break;

            case OK:

                message = "成功";

                break;

        }

        this.message = message;

    }

    public static ResponseData create(int code, Object data) {

        ResponseData responseData = new ResponseData();

        responseData.code = code;

        responseData.generateMessage(code);

        responseData.data = data;

        return responseData;

    }

    public static ResponseData create(int code) {

        return create(code, null);

    }

    public static ResponseData ok(Object data) {

        return ResponseData.create(ResponseData.OK, data);

    }

    public static ResponseData ok() {

        return ResponseData.create(ResponseData.OK, null);

    }

    public static ResponseData no(int code, Object data) {

        return ResponseData.create(code, data);

    }

    public static ResponseData no(int code) {

        return ResponseData.create(code);

    }

}

启动Spring Boot应用的方式有很多种:

• 作为一个 Java 应用程序, 可以直接通过运行拥有 main 函数的类来启动。

• 在 Maven 配置中, 之前提到了 spring-boot 插件, 可以使用它来启动, 比如执行 mvn spring-boot: run 命令。

• 在服务器上部署运行时, 通常先使用 mvn install 将应用打包成 jar 包, 再通过 java -jar xxx. jar 来启动应用。

配置详解

   在面我们轻松地实现了一个简单的RESTfulAPI应用, 体验了SpringBoot的 诸多优点。我们用非常少的代码就成功实现了一个Web应用, 这是传统Spring应用无法办到的。虽然在实现Controller时用到的代码是一样的,但是在配置方面,相信大家也注意到了, 在上面的例子中, 除了Maven的配置之外, 没有引入任何其他配置。 

    这就是之前我们提到的,SpringBoot针对常用的开发场景提供了一系列自动化配置来 减少原本复杂而又几乎很少改动的模板化配置内容。但是,我们还是需要 了解如何在Spring Boot中修改这些自动化的配置内容, 以应对一些 特殊的场景需求, 比如, 我们在同一台主 机上需要启动多个基千Spring Boot的Web应用, 若不为每个应用指定特别的端口号, 那 么默认的8080 端口必将导致冲突。 后续我们在使用SpringCloud的各个组件的时候, 其实有大量的工作都 会是针对配置 文件的。所以我们有必要深入了解一些关于SpringBoot中的配置文件的知识, 比如配置方 式、 如何实现多环境配置、 配置信息的加载顺序等。

  • 配置文件

     

    在快速入门示例中, 我们介绍Spring Boot 的工程结构时, 提到过 src/rnain/ resources 目录是Spring Boot的配置目录, 所以当要为应用创建个性化配置时, 应在该 目录下进行。

    Spring Boot 的默认配置文件位置为 src/main/resources/application. properties 。关于SpringBoot应用的配置内容都可以集中在该文件中, 根据我们引入的 不 同Starter模块,可以在这里定义容器端口号、 数据库连接信息、 日志级别等各种配置信 息。比如, 我们需要自定义Web模块的服务端口号,可以在application.properties  中添加 server.port=8888 来指定服务端口为 8888 , 也可 以通过 spring.appliction.name =hello 来指定应用名(该名字在后续SpringCloud中会被 注册为服务名)。 

    Spring Boot的配置文件除了可以使用传统的 properties文件之外,还支持现在被广泛推 荐使用的YAML文件。

    YAML 采用的配置格式不像 properties 的配置那样以单纯的键值对形式来表示,而是以 类似大纲的缩进形式来表示。 下面是一段 YAML 配置信息:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

server:    

    port: 8081

spring:    

    profiles:        

        active: prod

mybatis:    

    mapper-locations: classpath:mapping/*.xml    

    type-aliases-package: com.baihe.dms.entity.common    

    configLocation: classpath:mybatis-config.xml

logging:    

    level:        

        com.baihe.dms.mapper: debug

endpoints:    

    shutdown:        

        enabled: true    

    sensitive:      

        false

  • 自定义参数

    除了可以在 Spring Boot 的配置文件中设置各个 Starter 模块中预定义的配置属性, 也可 以在配置文件中定义一些我们需要的自定义属性。 比如在 application.properties 中 添加: book.name=SpringCloudinAction

    book.author=ZhaiYongchao

    然后, 在应用中可以通过@Value 注解来加载这些自定义的参数,

    比如:

    @Component

    public class Book {

    @Value("${book.name}")

    private String name;

    @Value("${book.author}")

    private String author;

    //省略getter和setter @Value 注解加载属性值的时候可以支持两种表达式来进行配置,

    如下所示。

    • 一种是上面介绍的 PlaceHolder 方式, 格式为${...}, 大括号内为 PlaceHolder。

    • 另一种是使用SpEL 表达式 (Spring Expression Language), 格式为#{...}, 大括号 内为 SpEL 表达式。

  • 使用随机数

    在 一些特殊情况下, 我们希望有些参数每次被加载的时候不是 一个固定的值, 比如密 钥、 服务端口等。 在 SpringBoot的属性配置文件中, 可以 通过 使用${random}配置来产 生随机的int值、long值或者string字符串,这样我们就可以容易地通过 配置随机生成属性, 而不是在程序中通过编码来实现这些逻辑。

    #随机字符串 com.didispace.blog.value=${random.value}

    #随机int com.didispace.blog.number=${random.int}

    #随机long com.didispace.blog.bignumber=${random.long}

    # 10以内的随机数 com.didispace.blog.test1=${random.int(l0)}

    # 10-20的随机数 com.didispace.blog.test2=${random.int[l0,20]}

  • 命令行参数

    在用命令行方式 启 动 Spring Boot 应用时, 连续的两个减号--就 是对 application.properties 中的属性值进行赋值 的标识。 所以 , java -jar xxx.jar--server.port=8888命令, 等价千在 application.properties 中添加 属性server.port= 8888。 通过命令行来修改属性值是 SpringBoot非常重要的一个特性。 通过此特性, 理论上已经使得应用的属性在启动前是可变的, 所以其中的端口号也好、 数据库连接也好, 都是可 以在应用启动时发生改变的, 而不同于以往的Spring应用通过Maven的Profile在编译器 中进行不同环境的构建。 SpringBoot的这种方式, 可以让应用程序的打包内容贯穿开发、 测试以及线上部署, 而Maven不同Profile的方案为每个环境所构建的包,其内容本质上是 不同的。 但是, 如果 每个参数都需要通过命令行来指定, 这显然也不是 一个好的方案, 所 以下面我们看看如何在SpringBoot中实现多环境的配置。

  • 多环境配置

    我们在开发应用的时候, 通常同一套程序会被应用和安装到几个不同的环境中, 比如 开发 、 测试、 生产等。 其中 每个环境的数据库地址、 服务器端口等配置都不同, 如果在为 不同环境打包时都要频繁修改配置文件的话, 那必将是个非常烦琐且容易发生错误的事。 对于多环境的配置,各种项目构建工具或是框架的基本思路是 一致的, 通过配置多份 不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,SpringBoot 也不 例外, 或者说实现起来更加简单。

    在 Spring Boot 中, 多环境配置的文件名需要满足 application-{profile}. proper巨es的格式, 其中{profile}对应你的环境标识,

    如下所示。

    • applicaction-dev.properties: 开发环境。

    • applicaction-test.properties: 测试环境。

    • application-prod.properties: 生产环境。

    至于具体哪个配置文件会被加载, 需要在 application.properties 文件中通过 spring.profiles.active 属性来设置, 其 值 对应配置文件中的{profile}值。 如 spring.profiles.active= test就会加载 application-test.properties配置 文件内容。

  • 加载顺序

    为了能够更合理地重写各属性的值,SpringBoot使用了下面这种较为特别的属性加载 顺序:

    1 在命令行中传入的参数。

    2. SPRING APPLICATION JSON中的属性。 SPRING_APPLICATION—JSON是以 JSON格式配置在系统环境变量中的内容。

    3. java:comp/env中的JNDI 属性。

    4. Java的系统属性, 可以通过System.getProperties()获得的内容。

    5 操作系统的环境变量 。

    6 通过random.*配置的随机属性。

    7 位于当前应用 jar 包之外,针对不同{profile}环境的配置文件内容,例如 application-{profile}.properties或是YAML定义的配置文件。

    8 位于当前应用 jar 包之内 ,针对不同{profile}环境的配置文件内容,例如 application-{profile}.properties或是YAML定义的配置文件。

    9 位于当前应用jar包之外的application.properties和YAML配置内容。

    10位于当前应用jar包之内的application.properties和YAML配置内容。

    11在@Configura巨on注解修改的类中,通过@PropertySource注解定义的属性。

    12应用默认属性,使用SpringApplication.setDefaultProperties 定义的 内容。

    优先级按上面的顺序由高到低,数字越小优先级越高。


 

相关实践学习
MySQL基础-学生管理系统数据库设计
本场景介绍如何使用DMS工具连接RDS,并使用DMS图形化工具创建数据库表。
相关文章
|
2月前
|
JSON Java API
利用Spring Cloud Gateway Predicate优化微服务路由策略
Spring Cloud Gateway 的路由配置中,`predicates`​(断言)用于定义哪些请求应该匹配特定的路由规则。 断言是Gateway在进行路由时,根据具体的请求信息如请求路径、请求方法、请求参数等进行匹配的规则。当一个请求的信息符合断言设置的条件时,Gateway就会将该请求路由到对应的服务上。
185 69
利用Spring Cloud Gateway Predicate优化微服务路由策略
|
2月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
303 69
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
29天前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
233 17
Spring Boot 两种部署到服务器的方式
|
18天前
|
存储 NoSQL Java
使用Java和Spring Data构建数据访问层
本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
61 21
|
1月前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
103 17
|
30天前
|
监控 Java API
【潜意识Java】使用SpringBoot构建高效的RESTfulAPI
本文介绍了使用Spring Boot构建RESTful API的完整流程,涵盖从项目创建到API测试的各个步骤。
49 1
|
10天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
1月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
2月前
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
463 13
Spring Cloud Alibaba:一站式微服务解决方案
|
2月前
|
运维 监控 Java
为何内存不够用?微服务改造启动多个Spring Boot的陷阱与解决方案
本文记录并复盘了生产环境中Spring Boot应用内存占用过高的问题及解决过程。系统上线初期运行正常,但随着业务量上升,多个Spring Boot应用共占用了64G内存中的大部分,导致应用假死。通过jps和jmap工具排查发现,原因是运维人员未设置JVM参数,导致默认配置下每个应用占用近12G内存。最终通过调整JVM参数、优化堆内存大小等措施解决了问题。建议在生产环境中合理设置JVM参数,避免资源浪费和性能问题。
130 3