《SpringCloud超级入门》Spring Boot项目搭建步骤(超详细)《六

}

}

@RestController 是 @Controller 和 @ResponseBody 的组合注解,可以直接返回 Json 格式数据。

运行结果

运行结果

读取配置文件


在以前的项目中我们主要在 XML 文件中进行框架配置,业务的相关配置会放在属性文件中,然后通过一个属性读取的工具类来读取配置信息。

Spring Boot 中的配置通常放在 application.properties 中,读取配置信息非常方便,总共分为 3 种方式。

1)Environment

可以通过 Environment 的 getProperty 方法来获取想要的配置信息,代码如下所示。

@RestController

public class HelloController {

// 注入对象

@Autowired

private Environment env;

@GetMapping(“/hello”)

public String hello() {

// 读取配置

String port = env.getProperty(“server.port”);

return port;

}

}

2)@Value

可以注入具体的配置信息,代码如下。

@RestController

public class HelloController {

// 注入配置

@Value(“${server.port}”)

private String port;

@GetMapping(“/hello”)

public String hello() {

return port;

}

}

3)自定义配置类

prefix 定义配置的前缀,代码如下。

@ConfigurationProperties(prefix = “net.biancheng”)

@Component

public class MyConfig {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

读取配置的方法代码如下。

@RestController

public class HelloController {

@Autowired

private MyConfig myConfig;

@GetMapping(“/hello”)

public String hello() {

return myConfig.getName();

}

}

定义配置 application.properties 的方法如下:

net.biancheng.name=zhangsan

profiles 多环境配置


在平时的开发中,项目会被部署到测试环境、生产环境,但是每个环境的数据库地址等配置信息都是不一样的。通过 profile 来激活不同环境下的配置文件就能解决配置信息不一样的问题。在 Spring Boot 中可以通过 spring.profiles.active=dev 来激活不同环境下的配置。

可以定义多个配置文件,每个配置文件对应一个环境,格式为 application-环境.properties,如表 1 所示。

在开发环境中,可以通过修改 application.properties 中的 spring.profiles.active 的值来激活对应环境的配置,在部署的时候可以通过 java–jar xxx.jar–spring.profiles.active=dev 来指定使用对应的配置。

热部署


开发过程中经常会改动代码,此时若想看下效果,就不得不停掉项目然后重启。

对于 Spring Boot 项目来说,启动时间是非常快的,在微服务的架构下,每个服务只关注自己的业务,代码量也非常小,这个启动时间是可以容忍的。

通过 spring-boot-devtools 就可以实现热部署。

只需要添加 spring-boot-devtools 的依赖即可实现热部署功能,代码如下所示。

org.springframework.boot

spring-boot-devtools

actuator 监控


Spring Boot 提供了一个用于监控和管理自身应用信息的模块,它就是 spring-boot-starter-actuator。该模块使用起来非常简单,只需要加入依赖即可,代码如下。

org.springframework.boot

spring-boot-starter-actuator

启动项目我们会发现在控制台输出的内容中增加了 所示的信息。

比如,我们访问 /actuator/health 可以得到下面的信息:

{

“status”: “UP”

}

Spring Boot启动控制台输出

Spring Boot启动控制台输出

Actuator端点信息

UP 表示当前应用处于健康状态,如果是 DOWN 就表示当前应用不健康。增加下面的配置可以让一些健康信息的详情也显示出来:

management.endpoint.health.show-details=ALWAYS

再次访问 /actuator/health,就可以得到健康状态的详细信息数据:

{

“status”: “UP”,

“diskSpace”: {

“status”: “UP”,

“total”: 491270434816,

“free”: 383870214144,

“threshold”: 10485760

}

}

大部分端点默认都不暴露出来,我们可以手动配置需要暴露的端点。如果需要暴露多个端点,可以用逗号分隔,如下所示:

management.endpoints.web.exposure.include=configprops,beans

如果想全部端点都暴露的话直接配置成下面的方式:

management.endpoints.web.exposure.include=*

后面我们会介绍如何使用 Spring Boot Admin在页面上更加直观地展示这些信息,目前都是 Json 格式的数据,不方便查看。

自定义 actuator 端点


我们需要自定义一些规则来判断应用的状态是否健康,可以采用自定义端点的方式来满足多样性的需求。如果我们只是需要对应用的健康状态增加一些其他维度的数据,可以通过继承 AbstractHealthIndicator 来实现自己的业务逻辑。代码如下。

@Component

public class UserHealthIndicator extends AbstractHealthIndicator {

@Override

protected void doHealthCheck(Builder builder) throws Exception {

builder.up().withDetail(“status”, true);

// builder.down().withDetail(“status”, false);

}

}

通过 up 方法指定应用的状态为健康,down 方法指定应用的状态为不健康。withDetail 方法用于添加一些详细信息。访问 /actuator/health,可以得到我们自定义的健康状态的详细信息:

{

“status”: “UP”,

“details”: {

“user”: {

“status”: “UP”,

“details”: {

“status”: true

}

},

“diskSpace”: {

“status”: “UP”,

“details”: {

“total”:

249795969024,

“free”: 7575375872,

“threshold”: 10485760

}

}

}

}

上面我们是在框架自带的 health 端点中进行扩展,还有一种需求是完全开发一个全新的端点,比如查看当前登录的用户信息的端点。自定义全新的端点很简单,通过 @Endpoint 注解就可以实现。代码如下所示。

@Component

@Endpoint(id = “user”)

public class UserEndpoint {

@ReadOperation

public List<Map<String, Object>> health() {

List<Map<String, Object>> list = new ArrayList<>();

Map<String, Object> map = new HashMap<>();

map.put(“userId”, 1001);

map.put(“userName”, “zhangsan”);

list.add(map);

return list;

}

}

访问 /actuator/user 可以看到返回的用户信息如下:

[

{

“userName”: “zhangsan”,

“userId”: 1001

}

]

统一异常处理


对于接口的定义,我们通常会有一个固定的格式

{

“status”: true,

“code”: 200,

“message”: null,

“data”: [

{

“id”: “101”,

“name”: “jack”

},

{

“id”: “102”,

“name”: “jason”

}

]

}

如果调用方在请求我们的 API 时把接口地址写错了,就会得到一个 404 错误:

{

“timestamp”: 1492063521109,

“status”: 404,

“error”: “Not Found”,

“message”: “No message available”,

“path”: “/rest11/auth”

}

后端服务会告诉我们哪个地址没找到,其实也挺友好。但是因为我们上面自定义的数据格式跟下面的不一致,所以当用户拿到这个返回的时候是无法识别的,其中最明显的是 status 字段。

我们自定义的是 boolean 类型,用来表示请求是否成功,这里返回的就是 Http 的状态码,所以我们需要在发生这种系统错误时也能返回我们自定义的那种格式,那就要定义一个异常处理类(代码如下所示),通过这个类既可以返回统一的格式,也可以统一记录异常日志。

@ControllerAdvice

public class GlobalExceptionHandler {

private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(value = Exception.class)

@ResponseBody

public ResponseData defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {

logger.error(“”, e);

ResponseData r = new ResponseData();

r.setMessage(e.getMessage());

if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {

r.setCode(404);

} else {

r.setCode(500);

}

r.setData(null);

r.setStatus(false);

return r;

}

}

ResponseData 是我们返回格式的实体类,其发生错误时也会被捕获到,然后封装好返回格式并返回给调用方。在 Spring Boot 的配置文件中加上如下代码所示配置。

出现错误时, 直接抛出异常

spring.mvc.throw-exception-if-no-handler-found=true

不要为我们工程中的资源文件建立映射

spring.resources.add-mappings=false

当我们调用一个不存在的接口时,返回的错误信息就是我们自定义的那种格式:

{

“status”: false, “code”: 404,

“message”: “No handler found for GET /rest11/auth”, “data”: null

}

最后贴上 ResponseData 的定义,代码如下。

public class ResponseData {

private Boolean status = true;

private int code = 200;

private String message;

private Object data;

// get set …

}

异步执行


异步调用就是不用等待结果的返回就执行后面的逻辑;同步调用则需要等待结果再执行后面的逻辑。

通常我们使用异步操作时都会创建一个线程执行一段逻辑,然后把这个线程丢到线程池中去执行,代码如下所示。

ExecutorService executorService = Executors.newFixedThreadPool(10);

executorService.execute(() -> {

try {

// 业务逻辑

} catch (Exception e) {

e.printStackTrace();

} finally {

}

});

这种方式尽管使用了 Java 的 Lambda,但看起来没那么优雅。在 Spring 中有一种更简单的方式来执行异步操作,只需要一个 @Async 注解即可,代码如下所示。

@Async

public void saveLog() {

System.err.println(Thread.currentThread().getName());

}

我们可以直接在 Controller 中调用这个业务方法,它就是异步执行的,会在默认的线程池中去执行。需要注意的是,一定要在外部的类中去调用这个方法,如果在本类调用则不起作用,比如 this.saveLog()。最后在启动类上开启异步任务的执行,添加 @EnableAsync 即可。

@Configuration

@ConfigurationProperties(prefix = “spring.task.pool”)

public class TaskThreadPoolConfig {

// 核心线程数

private int corePoolSize = 5;

// 最大线程数

private int maxPoolSize = 50;

// 线程池维护线程所允许的空闲时间

private int keepAliveSeconds = 60;

// 队列长度

private int queueCapacity = 10000;

// 线程名称前缀

private String threadNamePrefix = “FSH-AsyncTask-”;

// get set …

}

然后我们重新定义线程池的配置,代码如下所示。

最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分

中调用这个业务方法,它就是异步执行的,会在默认的线程池中去执行。需要注意的是,一定要在外部的类中去调用这个方法,如果在本类调用则不起作用,比如 this.saveLog()。最后在启动类上开启异步任务的执行,添加 @EnableAsync 即可。

@Configuration

@ConfigurationProperties(prefix = “spring.task.pool”)

public class TaskThreadPoolConfig {

// 核心线程数

private int corePoolSize = 5;

// 最大线程数

private int maxPoolSize = 50;

// 线程池维护线程所允许的空闲时间

private int keepAliveSeconds = 60;

// 队列长度

private int queueCapacity = 10000;

// 线程名称前缀

private String threadNamePrefix = “FSH-AsyncTask-”;

// get set …

}

然后我们重新定义线程池的配置,代码如下所示。

[外链图片转存中…(img-uZcYPggx-1714486792133)]

最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分

[外链图片转存中…(img-Bwd5hUMi-1714486792133)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 30
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba 是阿里巴巴提供的基于 Spring Cloud 的开源框架,用于构建微服务架构的应用程序。它提供了一套完整的分布式系统解决方案,包括服务注册与发现、配置管理、负载均衡、熔断器、限流器等核心组件,为开发者提供了高可用、高可靠、高性能的微服务开发环境。 要学习 Spring Cloud Alibaba 并应用于项目实战,可以按照以下步骤进行: 1. 学习基础知识:先了解 Spring Cloud 和 Alibaba 的相关概念和技术栈,包括 Spring Cloud Netflix、Spring Cloud Gateway、Nacos、Sentinel 等。 2. 搭建环境:根据项目需求,选择合适的开发工具和环境,如 IntelliJ IDEA、Eclipse、Maven、JDK 等,并配置好相关依赖。 3. 创建微服务应用:通过 Spring Initializr 创建一个基础的 Spring Boot 项目,并添加 Spring Cloud Alibaba 的相关依赖。 4. 配置服务注册与发现:使用 Nacos 注册中心,将微服务的信息注册到 Nacos 中,并实现服务之间的调用和发现。 5. 配置负载均衡:通过使用 Spring Cloud LoadBalancer 和 Nacos 客户端实现负载均衡,在多个实例之间分配请求负载。 6. 实现断路器和限流:使用 Sentinel 来实现服务的熔断和限流,保护系统免受高并发的冲击。 7. 使用分布式配置:通过 Nacos 实现配置中心,将应用程序的配置文件统一管理,并自动刷新配置。 8. 实现服务网关:使用 Spring Cloud Gateway 构建统一的入口,对外提供简化的 API,并进行请求过滤、路由转发等功能。 9. 监控和追踪:使用 SkyWalking 对微服务的性能和健康状态进行监控,并进行错误追踪和分析。 10. 测试和部署:编写测试用例,对微服务进行单元测试和集成测试,并使用 Docker、Kubernetes 等容器技术进行部署和管理。 通过以上步骤的学习和实践,逐步掌握 Spring Cloud Alibaba 的核心组件和功能,就可以从入门到项目实战了。但需要注意的是,只有持续学习和实践,并结合实际项目需求,才能不断提升自己在 Spring Cloud Alibaba 上的能力和经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值