zoukankan      html  css  js  c++  java
  • SpringCloud的介绍以及快速入门

    Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,
    如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
    Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,
    通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

    微服务中的相关概念:

      服务注册与发现:

        服务注册:服务实例将自身服务信息注册到注册中心。这部分服务信息包括服务所在主机IP和提供服务的Port,以及暴露服务自身状态以及访问协议等信息。
        服务发现:服务实例请求注册中心获取所依赖服务信息。服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。
      负载均衡:

        负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。
      熔断:

        熔断这一概念来源于电子工程中的断路器(Circuit Breaker)。在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,
        上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
      链路追踪:

        随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,
        这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。
        因此,就需要对一次请求涉及的多个服务链路进行日志记录,性能监控即链路追踪
      API网关:

        随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,
        如果让客户端直接与各个微服务通信可能出现:
          客户端需要调用不同的url地址,增加难度
          在一定的场景下,存在跨域请求的问题
          每个微服务都需要进行单独的身份认证
        针对这些问题,API网关顺势而生。
          API网关直面意思是将所有API调用统一接入到API网关层,由网关层统一接入和输出。一个网关的基本功能有:
            统一接入、安全防护、协议适配、流量管控、长短链接支持、容错能力。
            有了网关之后,各个API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问题。

    SpringCloud中的核心组件:

      Spring Cloud的本质是在 Spring Boot 的基础上,增加了一堆微服务相关的规范,并对应用上下文(Application Context)进行了功能增强。
      既然 Spring Cloud 是规范,那么就需要去实现,目前Spring Cloud 规范已由 Spring官方Spring Cloud Netflix,Spring Cloud Alibaba等实现。
      通过组件化的方式,Spring Cloud将这些实现整合到一起构成全家桶式的微服务技术栈。
      Spring Cloud Netflix组件:

        

       Spring Cloud Alibaba组件:

        

       Spring Cloud原生及其他组件:

        

      注册中心负责服务的注册与发现,很好将各服务连接起来
      断路器负责监控服务之间的调用情况,连续多次失败进行熔断保护。
      API网关负责转发所有对外的请求和服务
      配置中心提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息

      链路追踪技术可以将所有的请求数据记录下来,方便我们进行后续分析
      各个组件又提供了功能完善的dashboard监控平台,可以方便的监控各组件的运行状况

    快速入门:

      使用微服务架构的分布式系统,微服务之间通过网络通信。我们通过服务提供者与服务消费者来描述微服务间的调用关系。
        服务提供者:服务的被调用方,提供调用接口的一方
        服务消费者:服务的调用方,依赖于其他服务的一方
      以电商系统中常见的用户下单为例,用户向订单微服务发起一个购买的请求。在进行保存订单之前需要调用商品微服务查询当前商品库存,单价等信息。
      在这种场景下,订单微服务就是一个服务消费者,商品微服务就是一个服务提供者

        

      数据库表:

        商品表

    CREATE TABLE `tb_product` (
    `id` int(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

        订单表

    CREATE TABLE `tb_order` (
    `id` int(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

      搭建环境:

        1.创建父工程并引入坐标

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
        </parent>
    
        <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-logging</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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.32</version>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Greenwich.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    View Code

        2.创建微服务工程模块

          创建公共模块 common_service ,用于存放公共的实体类和工具类

          创建商品微服务模块 product_service

          创建订单微服务模块 order_service

        3.工程的依赖结构

          

      搭建公共模块:

        1.在common_service创建实体类

    /**
     * 商品实体类
     */
    @Data
    @Entity
    @Table(name="tb_product")
    public class Product {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String productName;
        private Integer status;
        private BigDecimal price;
        private String productDesc;
        private String caption;
        private Integer inventory;
    }
    View Code

      搭建商品微服务:

        1.在product_service的pom文件中引入坐标

    <dependency>
        <groupId>com.fgy</groupId>
        <artifactId>common_service</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency

        2.编写dao接口

    /**
     * 商品持久层接口
     */
    public interface ProductDao extends JpaRepository<Product,Long>, JpaSpecificationExecutor<Product> {
    }

        3.编写service层

    /**
     * 商品业务层接口
     */
    public interface ProductService {
    
        /**
         * 根据id查询
         * @return
         */
        Product findById(Long id);
    
        /**
         * 保存
         */
        void save(Product product);
    
        /**
         * 更新
         */
        void update(Product product);
    
        /**
         * 删除
         */
        void delete(Long id);
    }
    View Code
    /**
     * 商品业务层实现类
     */
    @Service
    public class ProductServiceImpl implements ProductService {
    
        @Autowired
        private ProductDao productDao;
    
        @Override
        public Product findById(Long id) {
            return productDao.findById(id).get();
        }
    
        @Override
        public void save(Product product) {
            productDao.save(product);
        }
    
        @Override
        public void update(Product product) {
            productDao.save(product);
        }
    
        @Override
        public void delete(Long id) {
            productDao.deleteById(id);
        }
    }
    View Code

        4.编写web层

    /**
     * 商品控制层
     */
    @RestController // 使用rest风格
    @RequestMapping("/product")
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @GetMapping(value = "/{id}")
        public Product findById(@PathVariable Long id) {
            Product product = productService.findById(id);
            return product;
        }
    
        @PostMapping
        public String save(@RequestBody Product product) {
            productService.save(product);
            return "保存成功";
        }
    }
    View Code

        5.配置启动类

    @SpringBootApplication
    @EntityScan("com.fgy.common.domain")
    public class ProductApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProductApplication.class,args);
        }
    }
    View Code

        6.配置yml文件

    server:
      port: 9001
    spring:
      application:
        name: service-product #服务名称
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf8
        username: root
        password: root
      jpa:
        database: MySQL
        show-sql: true
        open-in-view: true
    View Code

        7.在启动类启动测试

          访问:http://localhost:9001/product/1  返回商品信息的json字符串,则商品微服务可正常访问

      服务调用:

        前文已经编写了基础的微服务,在用户下单时需要调用商品微服务获取商品数据。那应该怎么做呢?
        商品微服务提供了供别人调用的HTTP接口。所以可以在下定单的时候使用http请求的相关工具类完成,如常见的HttpClient,OkHttp,当然也可以使用Spring提供的RestTemplate
          RestTemplate介绍:

            Spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。
            在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring 模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
            RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
            考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。
          RestTemplate方法介绍:

            

      搭建订单微服务,调用商品微服务:

        1.在order_service的pom文件中引入坐标

    <dependency>
        <groupId>com.fgy</groupId>
        <artifactId>common_service</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>

        2.编写web层

    /**
     * 订单控制层
     */
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        /**
         * 通过订单系统,调用商品服务根据id查询商品信息
         * @param id
         * @return
         */
        @GetMapping("/buy/{id}")
        public Product findById(@PathVariable("id") Long id) {
            return restTemplate.getForObject("http://localhost:9001/product/" + id, Product.class);
        }
    }
    View Code

        3.配置yml文件

    server:
      port: 9002
    spring:
      application:
        name: order-product #服务名称
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf8
        username: root
        password: root
      jpa:
        database: MySQL
        show-sql: true
        open-in-view: true
    View Code

        4.配置启动类

    @SpringBootApplication
    @EntityScan("com.fgy.common.domain")
    public class OrderApplication {
    
        // 配置RestTemplate交给spring管理
        @Bean
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(OrderApplication.class,args);
        }
    }
    View Code

    服务注册与发现Eureka:https://www.cnblogs.com/roadlandscape/p/12491040.html

  • 相关阅读:
    python-函数-实现学生管理系统,完成对学员的增,删,改,查和退出学生管理系统。
    python-函数-定义一个函数,实现两个数四则运算,要注意有3个参数,分别是运算符和两个运算的数字.
    Python-函数-continue、break、pass
    python-函数-写函数,接收n个数字,求这些数字的和
    python-函数-写函数,检查传入的字符串是否含有空字符串,返回结果,包含空字符串返回True,不包含返回False
    python-函数-写函数,判断用户传入的对象(列表)长度是否大于5,如果大于5,那么仅保留前五个长度的内容并返回。不大于5返回本身
    Python-函数-写函数,获取传入列表的所有奇数位索引对应的元素,并将其作为新列表返回
    PHP解析json字符串问题
    《算法技术手册》-Algorithms in a nutshell 作者: George T. Heineman
    PHP面向对象设计总结
  • 原文地址:https://www.cnblogs.com/roadlandscape/p/12491002.html
Copyright © 2011-2022 走看看