继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Spring Boot微服务教程:入门与实践指南

缥缈止盈
关注TA
已关注
手记 307
粉丝 34
获赞 152
概述

本文提供了详细的Spring Boot微服务教程,从Spring Boot的简介和优势开始,逐步介绍了如何创建和运行第一个Spring Boot微服务项目。接着深入讲解了微服务架构的基础知识,包括微服务的概念、优势以及与传统单体应用的区别。文章还详细展示了如何使用Spring Cloud Eureka构建服务注册中心,并通过Feign和Spring Cloud Stream实现服务间的通信。

Spring Boot 微服务教程:入门与实践指南
Spring Boot 简介

Spring Boot 是什么

Spring Boot是由Pivotal团队开发的一个基于Spring框架的开源项目。它为开发者提供了一种快速构建独立的、生产级别的应用的方式。Spring Boot的设计原则是“约定优于配置”,通过提供默认配置,极大地简化了开发过程。

Spring Boot 的优势

  1. 简化配置:Spring Boot提供了许多默认配置,降低了Spring框架的配置难度。
  2. 快速启动:使用Spring Boot可以快速启动应用,非常适合微服务的快速部署。
  3. 独立运行:Spring Boot应用可以独立运行,支持将应用打包为可执行的jar或war文件。
  4. 自动配置:通过约定优于配置的原则,Spring Boot会根据依赖的jar自动配置应用。
  5. 嵌入式的Servlet容器:Spring Boot可以内嵌Tomcat、Jetty或Undertow等Servlet容器,无需手动配置容器。
  6. 支持DevOps:Spring Boot提供了许多实用的特性,如嵌入式HTTP服务器、健康检查、运行时指标等,非常适合DevOps环境。

第一个 Spring Boot 项目

创建一个简单的Spring Boot项目,可以使用Spring Initializr(https://start.spring.io/)来生成。这里以IntelliJ IDEA为例,展示如何创建一个新的Spring Boot项目。

  1. 打开IntelliJ IDEA并选择“New Project”。
  2. 选择“Spring Initializr”并点击“Next”。
  3. 输入你的项目信息,如Group和Artifact。
  4. 在“Dependencies”中选择“Spring Web”和其他所需的依赖项。
  5. 点击“Next”并选择项目的保存位置。
  6. 点击“Finish”,项目将会创建并自动导入。

创建好项目后,可以在src/main/java目录下创建一个简单的REST控制器(Controller)。

package com.example.demo.controller;

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

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

上述代码创建了一个简单的REST控制器,通过@RestController注解让该类中的方法可以返回JSON或HTML内容。@GetMapping注解定义了HTTP GET请求的URL路径(/hello),当访问该路径时,会返回字符串"Hello, Spring Boot!"。

启动应用可以通过运行DemoApplication类中的main方法,该类通常位于src/main/java下的com.example.demo包中。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

DemoApplication类中,@SpringBootApplication注解是一个组合注解,包含了@Configuration@EnableAutoConfiguration@ComponentScan,这三个注解是Spring Boot应用的核心配置。

启动应用后,打开浏览器访问http://localhost:8080/hello,可以看到返回了"Hello, Spring Boot!",表示应用已经成功运行。

微服务基础

微服务的概念

微服务是一种架构风格,它将应用程序构建为一组小型、独立的服务,每个服务都有自己独立的进程,使用轻量级的通信机制(通常是HTTP或RPC)进行通信。每个服务负责执行特定的业务功能,并且可以独立部署、扩展和升级。微服务架构的核心目标是提高开发效率、加快部署速度、提高系统的可维护性和可扩展性。

微服务架构的优势

  1. 独立部署:每个微服务可以独立部署,不再需要整个系统重新部署。
  2. 可扩展性:可以根据需要独立扩展微服务,提高系统的响应能力和资源利用率。
  3. 容错性:由于每个微服务都是独立运行的,所以一个服务的故障不会影响到其他服务。
  4. 灵活性:每个服务可以使用最适合的技术栈,提高开发的灵活性。
  5. 持续交付:微服务的独立部署和测试使得持续交付变得更容易实现。
  6. 可维护性:每个服务的代码和配置文件独立,便于管理和服务的更新。
  7. 资源效率:通过按需分配资源,可以更有效地利用基础设施资源。

微服务与传统单体应用的区别

下表展示了微服务架构与传统单体应用的区别:

特性 单体应用 微服务应用
应用大小 单个程序,通常包含多个模块和功能 每个服务只包含一个或几个功能
组件间通信 调用程序内部的函数、类或对象 通过HTTP或RPC等协议进行通信
部署方式 重新部署整个应用或应用的一部分 可独立部署服务,不会影响其他服务
技术栈 统一的技术栈,一次选择,长期使用 可根据需要选择不同的技术栈
系统可扩展性 扩展整个应用,难以针对性扩展 可以针对性地扩展服务,提高效率
容错机制 整个应用出现故障时影响较大 单个服务故障不会影响其他服务的运行
维护和升级 找到问题的定位和修复相对复杂 每个服务独立,便于维护和升级
发布频率 发布周期较长,需要考虑整体影响 可频繁发布,每个服务的变更不会影响全局
性能优化 整体性能优化,难以针对性优化 可针对性优化服务,提高整体性能

为了更好地理解微服务架构与传统单体应用的区别,可以创建一个简单的示例应用。例如,假设有一个用户管理系统,包含用户注册、登录、用户信息查看等功能。在单体应用中,这些功能可能都在同一个项目中实现;而在微服务应用中,可以将其拆分为多个服务,如用户注册服务、用户登录服务、用户信息查看服务等。

创建单体应用示例

创建一个简单的Spring Boot项目,实现用户注册功能。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class UserRegistrationController {

    @GetMapping("/register")
    public String register(@RequestParam String username, @RequestParam String password) {
        // 这里可以调用服务,注册用户信息
        return "User " + username + " registered successfully!";
    }
}

创建微服务应用示例

创建多个Spring Boot项目,分别实现用户注册服务、用户登录服务、用户信息查看服务等。

// 用户注册服务
package com.example.demo.registration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class UserRegistrationService {

    @GetMapping("/register")
    public String register(@RequestParam String username, @RequestParam String password) {
        // 这里可以调用服务,注册用户信息
        return "User " + username + " registered successfully!";
    }
}

// 用户登录服务
package com.example.demo.login;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class UserLoginService {

    @GetMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        // 这里可以调用服务,登录用户信息
        return "User " + username + " logged in successfully!";
    }
}

// 用户信息查看服务
package com.example.demo.userinfo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class UserInfoService {

    @GetMapping("/getUserInfo")
    public String getUserInfo(@RequestParam String username) {
        // 这里可以调用服务,获取用户信息
        return "User " + username + " info retrieved successfully!";
    }
}

通过上述示例,可以更好地理解微服务架构与传统单体应用的区别。

构建第一个 Spring Boot 微服务

创建 Spring Boot 项目

开发微服务前,先创建一个新的Spring Boot项目。以Spring Initializr为例,创建一个新的Spring Boot Starter项目,选择Web依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

实现 RESTful API

使用Spring Boot实现RESTful API非常简单,只需创建一个REST控制器(Controller)并定义相应的HTTP请求映射(Mapping)即可。

package com.example.demo.controller;

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

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUserById(String id) {
        // 这里可以调用服务,获取用户信息
        return new User(id, "John Doe");
    }
}

在上述代码中,定义了一个UserController类,其中包含一个getUserById方法,该方法使用了@GetMapping注解,表明这是一个HTTP GET请求的处理器。方法参数id表示请求URL中的路径变量,这里用于获取指定ID的用户信息。

运行和测试微服务

运行Spring Boot应用的方式很简单,只需在DemoApplication类中调用SpringApplication.run方法即可。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

启动应用后,可以使用Postman或其他工具来测试RESTful API。例如,使用Postman发送GET请求到http://localhost:8080/users/1,返回用户信息。

微服务的注册与发现

服务注册中心介绍

在微服务架构中,服务注册中心是一个重要的组件,它负责管理和维护各个服务的注册信息。服务注册中心会记录每个服务的网络地址(IP地址和端口号),当服务启动时,会向注册中心注册自己,并在服务停止时注销自己。其他服务可以通过注册中心查找和调用需要的服务。

常见的服务注册中心有Eureka、Consul和Zookeeper等。这些注册中心不仅提供了服务注册和发现的功能,还可以实现健康检查、负载均衡等功能,为微服务架构提供了强有力的支持。

使用Spring Cloud Eureka构建注册中心

Spring Cloud提供了一系列工具支持开发分布式系统,其中Eureka是一个服务注册和发现的组件,提供服务注册和发现的功能。

  1. 添加依赖:在pom.xml文件中添加Spring Cloud Eureka的依赖。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  1. 配置Eureka Server:在application.yml文件中配置Eureka Server。
server:
  port: 8761
eureka:
  client:
  registerWithEureka: false
  fetchRegistry: false
  instance:
    hostname: localhost
  1. 启动Eureka Server:在DemoApplication类中添加@EnableEurekaServer注解。
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

启动应用后,Eureka Server会监听端口8761,并注册服务实例。

微服务的注册与发现实现

  1. 修改服务提供者:在服务提供者的application.yml文件中配置Eureka服务器地址。
spring:
  application:
    name: user-service
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  1. 启动服务提供者:服务提供者启动后会自动向Eureka Server注册。
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}
  1. 修改服务消费者:在服务消费者的application.yml文件中配置Eureka服务器地址,并使用RestTemplate发起请求。
spring:
  application:
    name: user-service-consumer
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
package com.example.demo.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class UserServiceConsumer {

    @Autowired
    private DiscoveryClient discoveryClient;

    public void getUserInfo() {
        DiscoveryClient discoveryClient = this.discoveryClient;
        ServiceInstance serviceInstance = discoveryClient.getInstances("user-service").get(0);
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();
        String url = "http://" + host + ":" + port + "/users/1";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
        System.out.println(response.getBody());
    }
}

启动服务消费者后,服务消费者会自动从Eureka Server获取服务提供者的地址,并进行HTTP请求。

服务间通信

REST通信与RPC通信

在微服务架构中,服务间通信是实现各个微服务之间协作的重要方式。常用的通信方式有REST(通过HTTP协议)和RPC(Remote Procedure Call,远程过程调用)。

REST通信

REST是一种架构风格,它基于HTTP协议实现服务间通信。RESTful API会定义一系列HTTP请求(GET、POST、PUT、DELETE等),这些请求映射到特定的资源操作。每个资源都有一个唯一的URL,客户端通过发送相应的HTTP请求来操作这些资源。这种方式简单、直观,易于实现。

RPC通信

RPC是一种编程范式,它允许一个程序调用另一个程序的函数,就像调用本地函数一样。RPC通常使用特定的协议(如XML-RPC、JSON-RPC)或者框架(如gRPC、Thrift)来实现。RPC通信更为复杂,但可以提供更好的性能和更强的功能,如双向通信、异步调用等。

使用Feign实现服务间的HTTP通信

Feign是一个基于Java的HTTP客户端,它使用了Spring Cloud的注解,简化了HTTP客户端的使用。Feign使得编写服务间HTTP调用变得非常简单。

  1. 添加依赖:在pom.xml文件中添加Feign的依赖。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 配置Feign:在application.yml文件中配置Feign。
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
  1. 定义Feign Client:创建一个接口,并使用@FeignClient注解说明这是Feign Client。
package com.example.demo.consumer;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "user-service")
public interface UserFeignClient {

    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") String id);
}
  1. 调用Feign Client:在服务消费者中注入并使用Feign Client。
package com.example.demo.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserServiceConsumerController {

    @Autowired
    private UserFeignClient userFeignClient;

    @GetMapping("/getUserById")
    public String getUserById() {
        User user = userFeignClient.getUserById("1");
        return "User: " + user.getName();
    }
}

使用Spring Cloud Stream进行消息驱动的通信

Spring Cloud Stream是一个构建消息驱动微服务的应用框架,它简化了消息中间件的使用。Spring Cloud Stream可以与多种消息中间件(如RabbitMQ、Kafka)集成,提供统一的编程模型。

  1. 添加依赖:在pom.xml文件中添加Spring Cloud Stream的依赖。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream</artifactId>
</dependency>
  1. 配置消息中间件:在application.yml文件中配置消息中间件。
spring:
  cloud:
    stream:
      bindings:
        output:
          destination: user-service-topic
      kafka:
        binder:
          brokers: localhost:9092
  1. 定义消息生产者:创建一个服务,并实现消息生产者的逻辑。
package com.example.demo.producer;

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;

@EnableBinding(Source.class)
public class UserMessageProducer {

    @Output(Source.OUTPUT)
    private MessageChannel output;

    @ServiceActivator(inputChannel = Source.OUTPUT)
    public void send(String message) {
        output.send(MessageBuilder.withPayload(message).build());
    }
}
  1. 定义消息消费者:创建一个服务,并实现消息消费者的逻辑。
package com.example.demo.consumer;

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.handler.annotation.Payload;

@EnableBinding(Sink.class)
public class UserMessageConsumer {

    @StreamListener(Sink.INPUT)
    public void receive(@Payload String message) {
        System.out.println("Received message: " + message);
    }
}

启动生产者和消费者后,生产者发送的消息会通过Kafka传递给消费者,从而实现服务间的异步通信。

微服务部署与监控

微服务的部署方式

微服务的部署方式可以有很多种,包括集中部署、分层部署、分布式部署等。每种部署方式都有其特点,适用于不同的应用场景。

集中部署

集中部署是指将所有微服务部署在同一个集群上,这种方式简单,便于管理和监控,但扩展性和容错性较差。

分层部署

分层部署是指将微服务按照业务逻辑分成多个层次,每个层次中的服务由一个或多个集群管理,这种方式可以提高系统的扩展性和容错性,但管理复杂度也会增加。

分布式部署

分布式部署是指将微服务部署在多个地理位置上,这种方式可以提高系统的可用性和性能,但需要考虑网络延迟和数据一致性等问题。

使用Docker部署微服务

Docker是一个开源的容器化技术,它通过将应用及其依赖打包为容器,使得应用可以在任何环境中保持一致的运行。使用Docker部署微服务可以极大地简化部署过程,提高系统的可移植性和可靠性。

  1. 构建Docker镜像:编写Dockerfile文件,定义如何构建Docker镜像。
FROM openjdk:8-jdk-alpine
ADD target/user-service.jar user-service.jar
ENTRYPOINT ["java","-jar","user-service.jar"]
  1. 构建镜像:使用Docker命令构建镜像。
docker build -t user-service .
  1. 运行容器:使用Docker命令运行容器。
docker run -p 8080:8080 user-service
  1. 持久化数据:可以将应用的持久化数据挂载到宿主机的目录上,以确保数据不会丢失。
docker run -v /host/path:/container/path -p 8080:8080 user-service

引入Spring Boot Actuator监控微服务

Spring Boot Actuator是一个Spring Boot的扩展模块,它提供了一系列工具帮助开发者监控和管理应用。通过使用Actuator,可以获取应用的运行时信息,如应用状态、线程信息、HTTP请求统计等。

  1. 添加依赖:在pom.xml文件中添加Actuator依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. 配置Actuator:在application.yml文件中配置Actuator。
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always
  1. 使用Actuator端点:启动应用后,可以通过HTTP请求访问Actuator提供的端点来获取应用的运行时信息。
curl http://localhost:8080/actuator

Spring Boot Actuator提供了多个HTTP端点,如/actuator/health/actuator/metrics等,可以通过这些端点获取应用的健康信息、内存信息、线程信息等。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP