微服務之服務搭建及遠程調用


服務拆分注意事項

單一職責:不同微服務,不要重復開發相同業務

數據獨立:不要訪問其它微服務的數據庫

面向服務:將服務暴露為接口,供其它微服務調用

簡單項目

需求:查詢訂單信息時將用戶信息也查詢

微服務分析:

  • 需要兩個服務UserService(操作用戶信息)、OrderService(操作訂單信息)
  • OrderService遠程調用UserService提供查詢用戶信息的方法

搭建工程

數據庫Sql語句

cloud-user數據庫中user表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人',
  `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, '柳岩', '湖南省衡陽市');
INSERT INTO `tb_user` VALUES (2, '文二狗', '陝西省西安市');
INSERT INTO `tb_user` VALUES (3, '華沉魚', '湖北省十堰市');
INSERT INTO `tb_user` VALUES (4, '張必沉', '天津市');
INSERT INTO `tb_user` VALUES (5, '鄭爽爽', '遼寧省沈陽市大東區');
INSERT INTO `tb_user` VALUES (6, '范兵兵', '山東省青島市');

SET FOREIGN_KEY_CHECKS = 1;
View Code

cloud-order數據庫中order表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '訂單id',
  `user_id` bigint(20) NOT NULL COMMENT '用戶id',
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名稱',
  `price` bigint(20) NOT NULL COMMENT '商品價格',
  `num` int(10) NULL DEFAULT 0 COMMENT '商品數量',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of tb_order
-- ----------------------------
INSERT INTO `tb_order` VALUES (101, 1, 'Apple 蘋果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新國標電動車', 209900, 1);
INSERT INTO `tb_order` VALUES (103, 3, '駱駝(CAMEL)休閑運動鞋女', 43900, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 雙模5G 驍龍865', 359900, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 雙模5G 視頻雙防抖', 299900, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷靜星II ', 544900, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人體工學電腦椅子', 79900, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休閑男鞋', 31900, 1);

SET FOREIGN_KEY_CHECKS = 1;
View Code

創建maven項目,父工程

pom配置

使用SpringBoot,需要添加父級:SpringBoot:2.3.9.RELEASE

依賴管理

  • SpringCloud:Hoxton.SR10(注意版本)
  • MySql、Mybatis
<packaging>pom</packaging>
    <!--父級節點-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.9.RELEASE</version>
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- mysql驅動 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
View Code

創建子模塊user-service、order-service

項目結構如下

編寫user-service

編寫pom

添加MySQL和mybatis依賴、maven插件(打包成可直接運行的 JAR 文件)

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <build>
        <!--jar包名稱-->
        <finalName>user-service</finalName>
        <plugins>
            <!--打包成可以直接運行的 JAR 文件(使用“java -jar”命令就可以直接運行)-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
View Code

配置application.yaml(配置服務器端口、數據庫連接、mybatis、logging)

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://192.168.223.129:3306/cloud-user?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  type-aliases-package: com.marw.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.marw: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
View Code

啟動類

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

pojo(Java Bean)

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}
View Code

mapper(數據庫操作)

public interface UserMapper {
    @Select("select * from tb_user where id = #{id}")
    User findById(@Param("id") Long id);
}
View Code

service(業務邏輯)

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id){
        return userMapper.findById(id);
    }
}
View Code

controller(暴露服務)

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryByid(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}
View Code

啟動項目

錯誤:Field userMapper in com.marw.service.UserService required a bean of type 'com.marw.mapper.UserMapper' that could not be found

原因:沒有將mapper放到spring容器中

解決:將mapper放到spring容器中

  方式一:添加@Mapper注解

@Mapper
public interface XxxMapper {
    ... ...
}

  方式二:通過掃描mapper所在的包

@SpringBootApplication
@MapperScan("com.marw.mapper") public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class,args);
    }
}

項目整體結構

測試

order-service和user-service類似,就不重復編寫,直接查看效果

發現user的數據為空,也就是說order服務需要調用user服務提供的方法

微服務遠程調用

遠程調用方式分析

瀏覽器通過http(http://localhost:8081/user/1)請求訪問user服務,如果order服務也能通過http(http://localhost:8081/user/1)請求訪問user服務

RestTemplate

spring提供發送http請求的工具

注冊RestTemplate

通過Bean注入(@Bean注解)將RestTemplate對象注冊到Spring容器中,就可以使用依賴注入方式(@Autowired)從Spring容器中獲取RestTemplate對象

Bean注入只能寫入Java配置類(被@Configuration注解的類)

@SpringBootApplication
@MapperScan("com.marw.mapper")
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }

 @Bean public RestTemplate restTemplate() { return new RestTemplate(); }
}

使用RestTemplate

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
 @Autowired private RestTemplate restTemplate;
    public Order queryById(Long id){
        Order order = orderMapper.findById(id);
        String url = "http://localhost:8081/user/"+order.getUserId(); User user = restTemplate.getForObject(url, User.class); order.setUser(user);
        return order;
    }
}

使用restTemplate方法getForObject還是postForObject等是根據請求方法所指定的請求方式決定的

測試

chorme的Json格式化工具下載地址:https://github.com/gildas-lormeau/JSONView-for-Chrome

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM