zoukankan      html  css  js  c++  java
  • 微服务之服务搭建及远程调用

    服务拆分注意事项

    单一职责:不同微服务,不要重复开发相同业务

    数据独立:不要访问其它微服务的数据库

    面向服务:将服务暴露为接口,供其它微服务调用

    简单项目

    需求:查询订单信息时将用户信息也查询

    微服务分析:

    • 需要两个服务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

  • 相关阅读:
    基于Cat的分布式调用追踪
    python3.8.0 Django 开发后端接口api 部署到 Linux Centos7上
    openlayers上添加点击事件
    openlayers在底图上添加静态icon
    vue中使用kindeditor富文本编辑器2
    openlayers绘制点,线,圆等
    openLayers绘制静态底图
    快速调用Android虚拟机
    flutter环境配置window10
    reactjs中配置代理跨域
  • 原文地址:https://www.cnblogs.com/WarBlog/p/15348825.html
Copyright © 2011-2022 走看看