supply and consumption
Article directory
Microservices belong to distributed systems. Microservices communicate through the network. There are many kinds of relationships between services, one of which is service-consumption.
For example, when buying a ticket, the user directly calls the ticket microservice, and the ticket microservice needs to call the user microservice to obtain user information and balance information, etc. In this scenario, the user microservice is the service provider, and the movie microservice A service is a service consumer.
Create a service provider
Taking the above scenario as an example, create a user microservice.
Initialize the project
Spring Initialzr creates a Springboot project (this article is version 2.7.10), pre-installed Springboot Web, lombok, Mysql Driver, Mybatis Framework four toolkits.
project configuration
micro-example1
Create a database in MYSQL
# 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 (create a new db directory under the resources directory)
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);
Define 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;
}
Write UserMapper
Define a method to query user records based on id
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);
}
Write the Service layer
- UserSerice interface
import com.evanpatchouli.example1.model.User;
public interface UserService {
User selById(Integer id);
}
- UserServiceImpl implementation
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);
}
}
Define the api interface return format
- 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 (tool class)
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);
}
}
Write the Controller layer
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);
}
}
Create a service consumer
Here to create a movie ticket microservice, the preparation work is similar, just install Springboot Web and lombok.
Configure the address of the User service
The purpose of writing in the configuration file is to facilitate management and change addresses
server.port=8080
spring.application.name=ticket-service
api.user-service=http://127.0.0.1:8081/user/
Create a RestTemplate Bean
Create a Bean that creates a RestTemplate in the entry class as a rest-api client
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 {
@Bean
public RestTemplate rest() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(TicketApplication.class, args);
}
}
Create UserApi
Create a UserApi component, use the rest client to call the query interface of the user service
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;
@Resource
private RestTemplate rest;
public Result findUserById(Integer id) {
//http://localhost:8081/user/:id
return rest.getForObject(baseUrl+id, Result.class);
}
}
Write the Controller layer
Define an interface for querying whether a ticket can be purchased, and pass in 2 parameters, the ticket price and the user id. Call UserApi in the interface to query user information, make a series of judgments (user exists? sufficient balance?), and finally return the result
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 {
@Resource
private 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);
}
}
Summarize
This is the simplest call between microservices, even without SpringCloud, but it shows us the relationship between service providers and consumers very concisely.