zoukankan      html  css  js  c++  java
  • 模拟微服务环境

    1 数据库表

    • 用户表:
    CREATE TABLE `tb_user` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(40) DEFAULT NULL COMMENT '用户名',
    `password` varchar(40) DEFAULT NULL COMMENT '密码',
    `age` int(3) DEFAULT NULL COMMENT '年龄',
    `balance` decimal(10,2) DEFAULT NULL COMMENT '余额',
    `address` varchar(80) DEFAULT NULL COMMENT '地址',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    • 商品表:
    CREATE TABLE `tb_product` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `product_name` varchar(40) DEFAULT NULL COMMENT '名称',
    `status` int(2) DEFAULT NULL COMMENT '状态',
    `price` decimal(10,2) DEFAULT NULL COMMENT '单价',
    `product_desc` varchar(255) DEFAULT NULL COMMENT '描述',
    `caption` varchar(255) DEFAULT NULL COMMENT '标题',
    `inventory` int(11) DEFAULT NULL COMMENT '库存',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
    
    INSERT INTO `tb_product` VALUES (1, 'iPhone', 1, 5000.10, '苹果手机就是香', '苹果哇', 50);
    
    • 订单表:
    CREATE TABLE `tb_order` (
    `id` bigint(11) NOT NULL AUTO_INCREMENT,
    `user_id` int(11) DEFAULT NULL COMMENT '用户id',
    `product_id` int(11) DEFAULT NULL COMMENT '商品id',
    `number` int(11) DEFAULT NULL COMMENT '数量',
    `price` decimal(10,2) DEFAULT NULL COMMENT '单价',
    `amount` decimal(10,2) DEFAULT NULL COMMENT '总额',
    `product_name` varchar(40) DEFAULT NULL COMMENT '商品名',
    `username` varchar(40) DEFAULT NULL COMMENT '用户名',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    2 搭建环境

    2.1 创建父工程spring_cloud_demo

    • 在IDEA中创建父工程spring_cloud_demo,并引入坐标:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <packaging>pom</packaging>
        <modules>
            <module>product_service</module>
            <module>spring_cloud_common</module>
            <module>order_service</module>
        </modules>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.2.RELEASE</version>
        </parent>
    
    
        <groupId>org.sunxiaping</groupId>
        <artifactId>spring_cloud_demo</artifactId>
        <version>1.0</version>
    
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.4</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Hoxton.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <repositories>
            <repository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>http://repo.spring.io/libs-snapshot-local</url>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>http://repo.spring.io/libs-milestone-local</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
            <repository>
                <id>spring-releases</id>
                <name>Spring Releases</name>
                <url>http://repo.spring.io/libs-release-local</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>http://repo.spring.io/libs-snapshot-local</url>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </pluginRepository>
            <pluginRepository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>http://repo.spring.io/libs-milestone-local</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </pluginRepository>
        </pluginRepositories>
        
    </project>
    

    2.2 创建微服务工程模块

    • 创建商品微服务模块spring_cloud_product。
    • 创建订单微服务模块spring_cloud_order。

    3 搭建商品微服务

    3.1 在pom.xml中导入相关jar包的坐标

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring_cloud_demo</artifactId>
            <groupId>org.sunxiaping</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>product_service</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>2.2.2.RELEASE</version>
                    <configuration>
                        <fork>true</fork>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    

    3.2 编写实体类

    • Product.java
    package com.sunxiaping.product.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @Entity
    @Table(name = "tb_product")
    public class Product implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name = "product_name")
        private String productName;
    
        @Column(name = "status")
        private Integer status;
    
        @Column(name = "price")
        private BigDecimal price;
    
        @Column(name = "product_desc")
        private String productDesc;
    
        @Column(name = "caption")
        private String caption;
    
        @Column(name = "inventory")
        private String inventory;
        
    }
    

    3.3 编写dao层

    • ProductDao.java
    package com.sunxiaping.product.dao;
    
    import com.sunxiaping.product.domain.Product;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
    
    }
    

    3.4 编写service层

    • ProductService.java
    package com.sunxiaping.product.service;
    
    import com.sunxiaping.product.domain.Product;
    
    public interface ProductService {
    
        /**
         * 根据id查询
         *
         * @param id
         * @return
         */
        Product findById(Long id);
    
    
        /**
         * 保存
         *
         * @param product
         */
        void save(Product product);
    
    
        /**
         * 更新
         *
         * @param product
         */
        void update(Product product);
    
    
        /**
         * 删除
         *
         * @param id
         */
        void delete(Long id);
    
    }
    
    • ProductServiceImpl.java
    package com.sunxiaping.product.service.impl;
    
    import com.sunxiaping.product.dao.ProductRepository;
    import com.sunxiaping.product.domain.Product;
    import com.sunxiaping.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import javax.transaction.Transactional;
    
    @Service
    @Transactional
    public class ProductServiceImpl implements ProductService {
    
        @Autowired
        private ProductRepository productRepository;
    
        @Override
        public Product findById(Long id) {
            return productRepository.findById(id).orElse(new Product());
        }
    
        @Override
        public void save(Product product) {
            productRepository.save(product);
        }
    
        @Override
        public void update(Product product) {
            productRepository.save(product);
        }
    
        @Override
        public void delete(Long id) {
            productRepository.deleteById(id);
        }
    }
    

    3.5 编写controller层

    • ProductController.java
    package com.sunxiaping.product.controller;
    
    import com.sunxiaping.product.domain.Product;
    import com.sunxiaping.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping(value = "/product")
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @PostMapping(value = "/save")
        public String save(@RequestBody Product product) {
            productService.save(product);
            return "新增成功";
        }
    
        @GetMapping(value = "/findById/{id}")
        public Product findById(@PathVariable(value = "id") Long id) {
            return productService.findById(id);
        }
    }
    

    3.6 配置yml文件

    • application.yml
    server:
      port: 9001 # 微服务的端口号
    
    spring:
      application:
        name: service-product # 微服务的名称
      datasource:
        url: jdbc:mysql://192.168.237.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: 123456
      jpa:
        generate-ddl: true
        show-sql: true
        open-in-view: true
        database: mysql
    

    3.7 配置启动类

    • ProductApplication.java
    package com.sunxiaping.product;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    
    @SpringBootApplication
    public class ProductApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProductApplication.class, args);
        }
    }
    

    4 搭建订单微服务

    4.1 在pom.xml中导入相关jar包的坐标

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring_cloud_demo</artifactId>
            <groupId>org.sunxiaping</groupId>
            <version>1.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>order_service</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

    4.2 编写实体类

    • Product.java
    package com.sunxiaping.order.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @Entity
    @Table(name = "tb_product")
    public class Product implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name = "product_name")
        private String productName;
    
        @Column(name = "status")
        private Integer status;
    
        @Column(name = "price")
        private BigDecimal price;
    
        @Column(name = "product_desc")
        private String productDesc;
    
        @Column(name = "caption")
        private String caption;
    
        @Column(name = "inventory")
        private String inventory;
        
    }
    

    4.3 配置yml

    • application.yml
    server:
      port: 9002 # 微服务的端口号
    
    spring:
      application:
        name: service-order # 微服务的名称
      datasource:
        url: jdbc:mysql://192.168.237.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: 123456
      jpa:
        generate-ddl: true
        show-sql: true
        open-in-view: true
        database: mysql
    

    4.4 配置启动类

    • OrderApplication.java
    package com.sunxiaping.order;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class OrderApplication {
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class, args);
        }
    }
    

    4.5 服务调用

    4.5.1 概述

    • 在用户下单的时候需要调用商品微服务获取商品数据,那么应该需要怎么做呢?商品微服务提供了供人调用的HTTP接口,所以下订单的时候使用HTTP请求的相关工具类完成,如常见的HttpClient、OkHttp,当然也可以使用Spring提供的RestTemplate。

    4.5.2 RestTemplate介绍

    • Spring框架提供的RestTemplate类可用于在应用中调用RESTful服务,它简化了和HTTP服务的通信方式,统一了RESTful的标准,封装了HTTP的链接,我们只需要传入URL和返回值类型即可。相较于之前常用的HttpClient、OkHttp等,RestTemplate是一种更加优雅的调用RESTful服务的方式。

    • 在Spring应用程序中访问第三方REST服务和Spring的RestTemplate类有关。RestTemplate类的设计原则和许多其他Spring模块类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。

    • RestTemplate默认依赖JDK提供HTTP连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为如Apache HttpComponents、Netty或OkHttp等其他HTTP库。

    • 考虑到RestTemplate类是为调用REST服务而设计的,因此他的主要方法和REST的基础紧密相连就不足为奇,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()等方法。

    4.6 向Spring容器中注册RestTemplate

    • SpringConfig.java
    package com.sunxiaping.order.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class SpringConfig {
    
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    4.7 编写下单方法

    • OrderController.java
    package com.sunxiaping.order.controller;
    
    import com.sunxiaping.product.domain.Product;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping(value = "/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        /**
         * 通过订单系统,调用商品微服务根据id查询商品信息
         *
         * @param id
         * @return
         */
        @GetMapping(value = "/buy/{id}")
        public Product buy(@PathVariable(value = "id") Long id) {
    
            Product product = restTemplate.getForObject("http://localhost:9001/product/findById/" + id, Product.class);
    
            return product;
        }
    }
    

    5 分析模拟微服务中存在的问题

    • 1️⃣服务调用者将微服务的请求路径硬编码到Java代码中。
    • 2️⃣不能​对微服务负载均衡的调用,因为请求路径的URL硬编码了。
    • 3️⃣服务多起来,对前端调用不友好,需要加入API网关。
    • 4️⃣微服务多起来的话,如果每次都需要重新修改配置文件,很麻烦,需要配置的统一管理。
    • 5️⃣链路追踪。
    • 6️⃣系统容错。
    • 7️⃣……

    分析模拟微服务中存在的问题

  • 相关阅读:
    Robberies HDU 2955
    P1474 货币系统 Money Systems(完全背包)(大水题)
    P1802 5倍经验日(01背包问题,水题)
    1621 花钱买车牌 (暴力一下就非常皮了)
    统计硬币 HDU 2566 (三种解法:线性代数解法,背包解法,奇思妙想解法 >_< )
    P1754 球迷购票问题
    Duwamish模式的Remoting注意事项(Remoting高手可以不必看了)
    Visual source safe 每日备份
    python第一篇
    pycharm的安装和使用
  • 原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/13726524.html
Copyright © 2011-2022 走看看