【SpringCloud微服务实践】提供与消费

news/2024/11/29 3:43:15/

提供与消费

文章目录

  • 提供与消费
    • 创建服务提供者
      • 初始化项目
      • 项目配置
      • 定义User
      • 编写UserMapper
      • 编写Service层
      • 定义api接口返回格式
      • 编写Controller层
    • 创建服务消费者
      • 配置User服务的地址
      • 创建RestTemplate Bean
      • 创建UserApi
      • 编写Controller层
    • 总结

微服务属于分布式系统,微服务之间通过网络通信,服务之间的关系可以有很多种,其中一种是服务-消费。
比如购票时,用户直接调用的是购票微服务,而购票微服务需要调用用户微服务来获取用户信息以及余额信息等等,在这个场景下,用户微服务是服务提供者,电影微服务是一个服务消费者。

创建服务提供者

以上面的情景为例,创建一个用户微服务。

初始化项目

Spring Initialzr 创建一个Springboot项目(本文是2.7.10版本),预装 Springboot Web, lombok, Mysql Driver, Mybatis Framework四个工具包。

项目配置

  • 在MYSQL中创建一个micro-example1数据库
# MySQL  
# 驱动  
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver  
# 数据库名  
spring.datasource.name=defaultDataSource  
# 数据库连接  
spring.datasource.url=jdbc:mysql://localhost:3306/micro-example1?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT  
# 用户名密码  
spring.datasource.username=root  
spring.datasource.password=root  
# 数据初始化  
spring.sql.init.schema-locations=classpath:db/schema.sql  
spring.sql.init.data-locations=classpath:db/data.sql  
spring.sql.init.mode=always  server.port=8081  spring.application.name=user-service
  • schema.sql(resources目录下新建db目录)
DROP TABLE IF EXISTS `user`;  
CREATE TABLE user (  `id` INTEGER AUTO_INCREMENT,  `username` VARCHAR(40),  `name` VARCHAR(20),  `age` INTEGER(3),  `balance` DECIMAL(10,2) COMMENT '余额',  PRIMARY KEY (`id`)  
);
  • data.sql
INSERT INTO user VALUES (1, 'user1', '用户1', 21, 100.00);  
INSERT INTO user VALUES (2, 'user2', '用户2', 22, 200.00);  
INSERT INTO user VALUES (3, 'user3', '用户3', 23, 300.00);

定义User

import lombok.AllArgsConstructor;  
import lombok.Data;  
import lombok.NoArgsConstructor;  import java.math.BigDecimal;  @Data  
@AllArgsConstructor  
@NoArgsConstructor  
public class User {  private Integer id;  private String username;  private String name;  private Integer age;  private BigDecimal balance;  
}

编写UserMapper

定义一个根据id查询user记录的方法

import com.evanpatchouli.example1.model.User;  
import org.apache.ibatis.annotations.Mapper;  
import org.apache.ibatis.annotations.Select;  
import org.springframework.stereotype.Repository;  @Mapper  
@Repository  
public interface UserMapper {  @Select("select * from user where id=#{id}")  User selById(Integer id);  
}

编写Service层

  • UserSerice接口
import com.evanpatchouli.example1.model.User;  public interface UserService {  User selById(Integer id);  
}
  • UserServiceImpl实现
import com.evanpatchouli.example1.mapper.UserMapper;  
import com.evanpatchouli.example1.model.User;  
import org.springframework.stereotype.Service;  import javax.annotation.Resource;  @Service  
public class UserServiceImpl implements UserService{  @Resource  private UserMapper userMapper;  @Override  public User selById(Integer id) {  return userMapper.selById(id);  }  
}

定义api接口返回格式

  • Result.java
import lombok.AllArgsConstructor;  
import lombok.Data;  
import lombok.NoArgsConstructor;  @AllArgsConstructor  
@NoArgsConstructor  
@Data  
public class Result<T> {  int code;  String msg;  T data;  
}
  • Resp.java(工具类)
public class Resp {  public static <T> Result ok(String msg, T data) {  return new Result(200,msg,data);  }  public static <T> Result fail(String msg, T data) {  return new Result(200,msg,data);  }  
}

编写Controller层

import com.evanpatchouli.example1.model.Result;  
import com.evanpatchouli.example1.model.User;  
import com.evanpatchouli.example1.service.UserService;  
import org.springframework.web.bind.annotation.*;  import javax.annotation.Resource;  @RestController  
@CrossOrigin  
@RequestMapping("/user")  
public class UserController<T> {  @Resource  private UserService userService;  @GetMapping("/{id}")  public Result<User> findById(@PathVariable Integer id) {  User user = userService.selById(id);  return new Result<>(200, "查找成功", user);  }  }

创建服务消费者

这里创建电影票微服务,准备工作类似,只安装Springboot Web和lombok即可。

配置User服务的地址

写在配置文件里的意图是便于管理和更改地址

server.port=8080
spring.application.name=ticket-service
api.user-service=http://127.0.0.1:8081/user/

创建RestTemplate Bean

入口类内创建一个创建RestTemplate的Bean,作为rest-api客户端

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class TicketApplication {@Beanpublic RestTemplate rest() {return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(TicketApplication.class, args);}}

创建UserApi

创建一个UserApi组件,使用rest客户端调用user服务的查询接口

import com.example.ticket.model.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@Component
public class UserApi {@Value("${api.user-service}")private String baseUrl;@Resourceprivate RestTemplate rest;public Result findUserById(Integer id) {//http://localhost:8081/user/:idreturn rest.getForObject(baseUrl+id, Result.class);}
}

编写Controller层

定义一个查询能不能买下票的接口,传入2参数,票价和用户id。在接口内调用UserApi查询用户信息,进行一系列的判断(用户存在?余额充足?),最后返回结果

import com.example.ticket.api.UserApi;
import com.example.ticket.model.Resp;
import com.example.ticket.model.Result;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.HashMap;@RestController
@CrossOrigin
@RequestMapping("/ticket")
public class TicketController {@Resourceprivate UserApi userApi;@GetMapping("/canibuy")public Result canIBuy(@RequestParam Double price, @RequestParam Integer id) {Result resp = userApi.findUserById(id);HashMap user = (HashMap) resp.getData();if (user==null){return Resp.fail("用户不存在",user);}if (price.compareTo((Double) user.get("balance")) > 0){return Resp.fail("余额不足",user);}return Resp.ok("余额充足", user);}
}

总结

这是一个最简单的微服务之间的调用,甚至都用不上SpringCloud,但很简洁得为我们展示了服务提供者和消费者之间的关系。


http://www.ppmy.cn/news/69854.html

相关文章

MySQL 字段为 NULL 的5大坑,大部分人踩过

数据库字段允许空值(null)的问题&#xff0c;小伙伴你遇到过吗&#xff1f; 在验证问题之前&#xff0c;我们先建一张测试表及测试数据。 构建的测试数据&#xff0c;如下图所示&#xff1a; 有了上面的表及数据之后&#xff0c;我们就来看当列中存在 NULL 值时&#xff0c;究…

调用百度文心AI作画API实现中文-图像跨模态生成

作者介绍 乔冠华&#xff0c;女&#xff0c;西安工程大学电子信息学院&#xff0c;2020级硕士研究生&#xff0c;张宏伟人工智能课题组。 研究方向&#xff1a;机器视觉与人工智能。 电子邮件&#xff1a;1078914066qq.com 一&#xff0e;文心AI作画API介绍 1. 文心AI作画 文…

web自动化测试进阶篇02 ——— BDD与TDD的研究实践

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

机器学习强基计划10-1:为什么需要集成学习?核心原理是什么?

目录 0 写在前面1 集成学习概念与优势2 结合策略梳理2.1 加权平均法2.2 投票法2.3 学习法 3 误差-分歧分解 0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器…

计算机图形学-GAMES101-8

引言 着色是针对某一个点(片段)的应用&#xff0c;这里需要考虑着色的频率。  漫反射项代表光向四面八方均匀的反射出去&#xff0c;和观察方向无关。  Blinn-Phong反射模型结构如下&#xff1a; ) 一、Blinn-Phong模型 &#xff08;1&#xff09;Specular 什么时候才能看到…

VOSviewer安装、环境配置及中英文文献的分析

VOSviewer介绍&#xff1a; VOSviewer是一个用于构建和可视化文献计量网络的软件工具。例如&#xff0c;这些网络可能包括期刊、研究人员或单个出版物&#xff0c;它们可以基于引文、书目耦合、共同引用或共同作者关系构建。VOSviewer 还提供文本挖掘功能&#xff0c;可用于构…

【夜莺(Flashcat)V6监控】3.链路追踪

链路追踪 介绍 链路追踪是分布式系统下的一个概念&#xff0c;它的目的就是要解决上面所提出的问题&#xff0c;也就是将一次分布式请求还原成调用链路&#xff0c;将一次分布式请求的调用情况集中展示&#xff0c;比如&#xff0c;各个服务节点上的耗时、请求具体到达哪台机…

Yarn安装及配置一件启停

Yarn安装及配置一件启停 数据、程序、运算资源&#xff08;内存、CPU)三者组在一起&#xff0c;才能完成数据的计算处理过程。在单机环境下&#xff0c;三者之间协调配合不是太大问题。为了应对海量数据的处理场景&#xff0c;Hadoop软件出现并提供了分布式处理思想。但是在分…