精华内容
参与话题
问答
  • 微服务Springcloud超详细教程+实战(一)

    万次阅读 多人点赞 2018-12-11 18:16:57
    认识微服务系统架构演变集中式架构/单体应用垂直拆分分布式服务服务治理(SOA) 系统架构演变 随着互联网的发展,网站应用的规模不断扩大。需求的激增,带来的是技术上的压力。系统架构也因此也不断的演进、升级、...

    如在文档中遇到什么问题请联系作者 QQ:1172796094
    本人正在找深圳Java实习工作,求大佬带飞
    ——————————————————————————————————————

    系统架构演变

    随着互联网的发展,网站应用的规模不断扩大。需求的激增,带来的是技术上的压力。系统架构也因此也不断的演进、升级、迭代。从单一应用,到垂直拆分,到分布式服务,到SOA,以及现在火热的微服务架构,还有在Google带领下来势汹涌的Service Mesh。我们到底是该乘坐微服务的船只驶向远方,还是偏安一隅得过且过?

    其实生活不止眼前的苟且,还有诗和远方。所以我们今天就回顾历史,看一看系统架构演变的历程;把握现在,学习现在最火的技术架构;展望未来,争取成为一名优秀的Java工程师。

    集中式架构/单体应用

    当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是影响项目开发的关键。
    在这里插入图片描述
    存在的问题:

    • 代码耦合,开发维护困难
    • 无法针对不同模块进行针对性优化
    • 无法水平扩展
    • 单点容错率低,并发能力差

    垂直拆分

    当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分:
    在这里插入图片描述
    优点:

    • 系统拆分实现了流量分担,解决了并发问题
    • 可以针对不同模块进行优化
    • 方便水平扩展,负载均衡,容错率提高
    • 系统间相互独立

    缺点:

    • 服务之间相互调用,如果某个服务的端口或者ip地址发生改变,调用的系统得手动改变
    • 搭建集群之后,实现负载均衡比较复杂

    分布式服务

    什么是分布式:将一个大的系统拆分成多个子系统

    当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。
    在这里插入图片描述
    优点:

    • 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率

    缺点:

    • 系统间耦合度变高,调用关系错综复杂,难以维护
    • 搭建集群之后,负载均衡比较难实现

    服务治理(SOA)

    OOP:面向对象编程

    AOP:面向切面编程

    SOA:面向服务编程

    当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键
    在这里插入图片描述
    阿里巴巴内部目前使用的框架:HSF(好舒服),是dubbo的升级版

    以前出现了什么问题?

    • 服务越来越多,需要管理每个服务的地址
    • 调用关系错综复杂,难以理清依赖关系
    • 服务过多,服务状态难以管理,无法根据服务情况动态管理

    服务治理要做什么?

    • 服务注册中心,实现服务自动注册和发现,无需人为记录服务地址
    • 服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系
    • 动态监控服务状态监控报告,人为控制服务状态

    缺点:

    • 服务间会有依赖关系,一旦某个环节出错会影响较大
    • 服务关系复杂,运维、测试部署困难,不符合DevOps思想(docker)

    OOP:面向对象

    AOP:面向切面

    SOA:面向服务

    前面说的SOA,英文翻译过来是面向服务的编程。微服务,似乎也是服务,都是对系统进行拆分。因此两者非常容易混淆,但其实却有一些差别:
    在这里插入图片描述
    微服务的特点:

    • 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
    • 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
    • 面向服务:面向服务是说每个服务都要对外暴露服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
    • 自治:自治是说服务间互相独立,互不干扰
      • 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
      • 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
      • 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动端开发不同接口
      • 数据库分离:每个服务都使用自己的数据源
      • 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护 Docker部署服务

    微服务结构图:
    在这里插入图片描述

    展开全文
  • 无论是微服务还是分布式服务(都是SOA,都是面向服务编程),都面临着服务间的远程调用。那么服务间的远程调用方式有哪些呢? 常见的远程调用方式有以下几种: RPC:Remote Produce Call远程过程调用,类似的还有...

    如在文档中遇到什么问题请联系作者 QQ:1172796094
    本人正在找深圳Java实习工作,求大佬带飞
    ——————————————————————————————————————

    远程调用方式

    无论是微服务还是分布式服务(都是SOA,都是面向服务编程),都面临着服务间的远程调用。那么服务间的远程调用方式有哪些呢?

    常见的远程调用方式有以下几种:

    • RPC:Remote Produce Call远程过程调用,类似的还有RMI(Remote Methods Invoke 远程方法调用,是JAVA中的概念,是JAVA十三大技术之一)。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型

      • RPC的框架:webservie(cxf)、dubbo
      • RMI的框架:hessian
    • Http:http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议。也可以用来进行远程服务调用。缺点是消息封装臃肿。

      现在热门的Rest风格,就可以通过http协议来实现。

      • http的实现技术:HttpClient
    • 相同点:底层通讯都是基于socket,都可以实现远程调用,都可以实现服务调用服务

    • 不同点:

    RPC:框架有:dubbo、cxf、(RMI远程方法调用)Hessian
    当使用RPC框架实现服务间调用的时候,要求服务提供方和服务消费方 都必须使用统一的RPC框架,要么都dubbo,要么都cxf
    
    跨操作系统在同一编程语言内使用
    优势:调用快、处理快
    
    
    http:框架有:httpClient
    当使用http进行服务间调用的时候,无需关注服务提供方使用的编程语言,也无需关注服务消费方使用的编程语言,服务提供方只需要提供restful风格的接口,服务消费方,按照restful的原则,请求服务,即可
    
    跨系统跨编程语言的远程调用框架
    优势:通用性强
    
    总结:对比RPC和http的区别
    1 RPC要求服务提供方和服务调用方都需要使用相同的技术,要么都hessian,要么都dubbo
      而http无需关注语言的实现,只需要遵循rest规范
    2 RPC的开发要求较多,像Hessian框架还需要服务器提供完整的接口代码(包名.类名.方法名必须完全一致),否则客户端无法运行
      
    3 Hessian只支持POST请求
    
    4 Hessian只支持JAVA语言
    

    认识RPC

    RPC,即 Remote Procedure Call(远程过程调用),是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。说得通俗一点就是:A计算机提供一个服务,B计算机可以像调用本地服务那样调用A计算机的服务。

    通过上面的概念,我们可以知道,实现RPC主要是做到两点:

    • 实现远程调用其他计算机的服务
      • 要实现远程调用,肯定是通过网络传输数据。A程序提供服务,B程序通过网络将请求参数传递给A,A本地执行后得到结果,再将结果返回给B程序。这里需要关注的有两点:
        • 1)采用何种网络通讯协议?
          • 现在比较流行的RPC框架,都会采用TCP作为底层传输协议
        • 2)数据传输的格式怎样?
          • 两个程序进行通讯,必须约定好数据传输格式。就好比两个人聊天,要用同一种语言,否则无法沟通。所以,我们必须定义好请求和响应的格式。另外,数据在网路中传输需要进行序列化,所以还需要约定统一的序列化的方式。
    • 像调用本地服务一样调用远程服务
      • 如果仅仅是远程调用,还不算是RPC,因为RPC强调的是过程调用,调用的过程对用户而言是应该是透明的,用户不应该关心调用的细节,可以像调用本地服务一样调用远程服务。所以RPC一定要对调用的过程进行封装

    RPC调用流程图:
    在这里插入图片描述
    想要了解详细的RPC实现,给大家推荐一篇文章:自己动手实现RPC

    认识Http

    Http协议:超文本传输协议,是一种应用层协议。规定了网络传输的请求格式、响应格式、资源定位和操作的方式等。但是底层采用什么网络传输协议,并没有规定,不过现在都是采用TCP协议作为底层传输协议。说到这里,大家可能觉得,Http与RPC的远程调用非常像,都是按照某种规定好的数据格式进行网络通信,有请求,有响应。没错,在这点来看,两者非常相似,但是还是有一些细微差别。

    • RPC并没有规定数据传输格式,这个格式可以任意指定,不同的RPC协议,数据格式不一定相同。
    • Http中还定义了资源定位的路径,RPC中并不需要
    • 最重要的一点:RPC需要满足像调用本地服务一样调用远程服务,也就是对调用过程在API层面进行封装。Http协议没有这样的要求,因此请求、响应等细节需要我们自己去实现。
      • 优点:RPC方式更加透明,对用户更方便。Http方式更灵活,没有规定API和语言,跨语言、跨平台
      • 缺点:RPC方式需要在API层面进行封装,限制了开发的语言环境。

    例如我们通过浏览器访问网站,就是通过Http协议。只不过浏览器把请求封装,发起请求以及接收响应,解析响应的事情都帮我们做了。如果是不通过浏览器,那么这些事情都需要自己去完成。
    在这里插入图片描述

    如何选择?

    既然两种方式都可以实现远程调用,我们该如何选择呢?

    • 速度来看,RPC要比http更快,虽然底层都是TCP,但是http协议的信息往往比较臃肿
    • 难度来看,RPC实现较为复杂,http相对比较简单
    • 灵活性来看,http更胜一筹,因为它不关心实现细节,跨平台、跨语言。

    因此,两者都有不同的使用场景:

    • 如果对效率要求更高,并且开发过程使用统一的技术栈,那么用RPC还是不错的。
    • 如果需要更加灵活,跨语言、跨平台,显然http更合适

    那么我们该怎么选择呢?

    微服务,更加强调的是独立、自治、灵活。而RPC方式的限制较多,因此微服务框架中,一般都会采用基于Http的Rest风格服务。

    展开全文
  • 如在文档中遇到什么问题...微服务场景模拟 首先,我们需要模拟一个服务调用的场景。方便后面学习微服务架构 服务提供者 我们新建一个项目,对外提供查询用户的服务。 创建数据库 CREATE TABLE `tb_user` ( `id` int...

    本人正在找深圳Java实习工作,求大佬带飞 QQ:1172796094
    如在文档中遇到什么问题请联系作者
    ——————————————————————————————————————

    微服务场景模拟

    首先,我们需要模拟一个服务调用的场景。方便后面学习微服务架构

    服务提供者

    我们新建一个项目,对外提供查询用户的服务。

    创建数据库

    CREATE TABLE `tb_user` (
      `id` int(11) NOT NULL,
      `user_name` varchar(50) DEFAULT NULL,
      `password` varchar(50) DEFAULT NULL,
      `name` varchar(50) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` int(11) DEFAULT NULL,
      `birthday` date DEFAULT NULL,
      `created` date DEFAULT NULL,
      `updated` date DEFAULT NULL,
      `note` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tb_user
    -- ----------------------------
    INSERT INTO `tb_user` VALUES ('1', 'tom', '123456', 'tom', '20', '1', '1999-11-29', '2018-11-29', '2018-11-29', null);
    INSERT INTO `tb_user` VALUES ('2', 'lucy', '123456', 'lucy', '20', '2', '2018-11-29', '2018-11-29', '2018-11-29', null);
    

    Spring脚手架创建工程

    借助于Spring提供的快速搭建工具:
    在这里插入图片描述
    填写项目信息:
    在这里插入图片描述
    添加web依赖:在这里插入图片描述
    添加mybatis依赖:
    在这里插入图片描述
    填写项目位置:
    在这里插入图片描述
    生成的项目结构:
    在这里插入图片描述
    依赖也已经全部自动引入:

    <?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>
    
    	<groupId>com.czxy.demo</groupId>
    	<artifactId>user-service-demo</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>user-service-demo</name>
    	<description>Demo project for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.0.4.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</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-jdbc</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.mybatis.spring.boot</groupId>
    			<artifactId>mybatis-spring-boot-starter</artifactId>
    			<version>1.3.2</version>
    		</dependency>
    
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    
    </project>
    

    当然,因为要使用通用mapper,所以我们需要手动加一条依赖:

    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>2.0.2</version>
    </dependency>
    

    ok!
    注意:SpringCloud中mysql驱动包默认是8.x,太高了,可能会引起问题,所以需要修改成5.x

    <dependency>  
      <groupId>mysql</groupId>   
       <artifactId>mysql-connector-java</artifactId> 
          <scope>runtime</scope>   
           <version>5.1.32</version>
     </dependency>
    

    编写代码

    添加一个对外查询的接口:

    @RestController
    @RequestMapping("user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/{id}")
        public User queryById(@PathVariable("id") Long id) {
            return this.userService.queryById(id);
        }
    }
    
    

    Service:

    @Service
    public class UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        public User queryById(Long id) {
            return this.userMapper.selectByPrimaryKey(id);
        }
    }
    

    mapper:

    @Mapper
    public interface UserMapper extends tk.mybatis.mapper.common.Mapper<User>{
    }
    

    实体类:

    @Table(name = "tb_user")
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        // 用户名
        private String userName;
    
        // 密码
        private String password;
    
        // 姓名
        private String name;
    
        // 年龄
        private Integer age;
    
        // 性别,1男性,2女性
        private Integer sex;
    
        // 出生日期
        private Date birthday;
    
        // 创建时间
        private Date created;
    
        // 更新时间
        private Date updated;
    
        // 备注
        private String note;
    
       // 。。。省略getters和setters
    }
    

    属性文件,这里我们采用了yaml语法,而不是properties:

    server:
      port: 8082
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/mydb1?useUnicode=true&characterEncoding=utf8
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      application:
        name: user-service # 应用名称
      main:
        allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
    #    druid:
    #      initial-size: 1
    #      min-idle: 1
    #      max-active: 20
    #      test-on-borrow: true
    #      stat-view-servlet:
    #        allow: true
    eureka:
      client:
        service-url: # EurekaServer地址
          defaultZone: http://127.0.0.1:10086/eureka
      instance:
        prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
        ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
    

    项目结构:
    在这里插入图片描述

    启动并测试:

    启动项目,访问接口:http://localhost:8081/user/1
    在这里插入图片描述
    未完待续~~~~~~

    展开全文
  • Spring-cloud微服务学习入门教程

    千次阅读 2017-09-04 18:29:54
    学习教程地址:https://github.com/eacdy/spring-cloud-book 学习教程源码:https://github.com/eacdy/spring-cloud-study 本文主要关注Eureka服务注册和发现,测试教程项目的简要过程和本人比较关注spring-cloud的...

    学习教程地址:https://github.com/eacdy/spring-cloud-book

    学习教程源码:https://github.com/eacdy/spring-cloud-study

    Spring-cloud微服务学习内容

    Spring-cloud微服务学习入门教程内容包括以下几点:

    • 服务发现(Eureka)
    • 服务提供者(Provider)
    • 服务消费者(Consumer)
    • 客户端负载均衡Ribbon
    • 简化的Http客户端Feign
    • 熔断器(Hystrix、Hystrix监控界面Hystrix Dashboard、Hystrix集群监控工具Turbine)
    • 配置中心
    • API Gateway

    Spring-cloud微服务项目运行测试

    将项目加入IDE目录:


    项目主机端口分配:

    项目名称端口描述URL
    microservice-api-gateway8050API Gateway详见文章
    microservice-config-client8041配置服务的客户端详见文章
    microservice-config-server8040配置服务详见文章
    microservice-consumer-movie-feign8020Feign Demo/feign/1
    microservice-consumer-movie-feign-with-hystrix8021Feign Hystrix Demo/feign/1
    microservice-consumer-movie-feign-with-hystrix-stream8022Hystrix Dashboard Demo/feign/1
    microservice-consumer-movie-ribbon8010Ribbon Demo/ribbon/1
    microservice-consumer-movie-ribbon-with-hystrix8011Ribbon Hystrix Demo/ribbon/1
    microservice-discovery-eureka8761注册中心/
    microservice-hystrix-dashboard8030hystrix监控/hystrix.stream
    microservice-hystrix-turbine8031turbine/turbine.stream
    microservice-provider-user8000服务提供者/1

    运行示例步骤:


    步骤(0):设置主机IP名称映射(必要,示例demo需要通过主机名访问):

    # Copyright (c) 1993-2009 Microsoft Corp.
    #
    # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
    #
    # This file contains the mappings of IP addresses to host names. Each
    # entry should be kept on an individual line. The IP address should
    # be placed in the first column followed by the corresponding host name.
    # The IP address and the host name should be separated by at least one
    # space.
    #
    # Additionally, comments (such as these) may be inserted on individual
    # lines or following the machine name denoted by a '#' symbol.
    #
    # For example:
    #
    #      102.54.94.97     rhino.acme.com          # source server
    #       38.25.63.10     x.acme.com              # x client host
    
    # localhost name resolution is handled within DNS itself.
    #	127.0.0.1       localhost
    #	::1             localhost
    
    
    0.0.0.1	mssplus.mcafee.com
    
    
    127.0.0.1       localhost discovery peer1 peer2 ribbon  config-server gateway

    步骤(1):启动microservice-discovery-eureka 主函数。

    步骤(2):启动microservice-provider-user 主函数。

    步骤(3):启动你要测试的其它任意demo。


    Spring-cloud核心知识点拨

    以下只记录本人比较关注的点和内容,ribbon、hystrix、feign、turbine和配置服务请到原文去了解。

    spring-cloud

    Spring Cloud是在Spring Boot的基础上构建的,用于简化分布式系统构建的工具集,为开发人员提供快速建立分布式系统中的一些常见的模式。

    例如:配置管理(configuration management),服务发现(service discovery),断路器(circuit breakers),智能路由( intelligent routing),微代理(micro-proxy),控制总线(control bus),一次性令牌( one-time tokens),全局锁(global locks),领导选举(leadership election),分布式会话(distributed sessions),集群状态(cluster state)。

    Spring Cloud 包含了多个子项目:

    例如:Spring Cloud Config、Spring Cloud Netflix等 Spring Cloud 项目主页:http://projects.spring.io/spring-cloud/

    微服务发现

    在微服务架构中,服务发现(Service Discovery)是关键原则之一。手动配置每个客户端或某种形式的约定是很难做的,并且很脆弱。Spring Cloud提供了多种服务发现的实现方式,例如:Eureka、Consul、Zookeeper。

    Spring Cloud支持得最好的是Eureka,其次是Consul,最次是Zookeeper。

    服务提供者和消费者

    名词概念
    服务提供者服务的被调用方(即:为其他服务提供服务的服务,如 microservice-provider-user)
    服务消费者服务的调用方(即:依赖其他服务的服务,如:microservice-consumer-movie-*)


    API Gateway

    此处文字来自:http://dockone.io/article/482

    通常来说,一个更好的解决办法是采用API Gateway的方式,可以理解为它是微服务接口的上层代理(Proxy)。API Gateway是一个服务器,也可以说是进入系统的唯一节点。这跟面向对象设计模式中的Facade模式很像。API Gateway封装内部系统的架构,并且提供API给各个客户端。它还可能有其他功能,如授权、监控、负载均衡、缓存、请求分片和管理、静态响应处理等。

    下图展示了一个适应当前架构的API Gateway。


    API Gateway负责请求转发、合成和协议转换。所有来自客户端的请求都要先经过API Gateway,然后路由这些请求到对应的微服务。API Gateway将经常通过调用多个微服务来处理一个请求以及聚合多个服务的结果。它可以在web协议与内部使用的非Web友好型协议间进行转换,如HTTP协议、WebSocket协议。

    API Gateway可以提供给客户端一个定制化的API。它暴露一个粗粒度API给移动客户端。以产品最终页这个使用场景为例。API Gateway提供一个服务提供点(/productdetails?productid=xxx)使得移动客户端可以在一个请求中检索到产品最终页的全部数据。API Gateway通过调用多个服务来处理这一个请求并返回结果,涉及产品信息、推荐、评论等。

    一个很好的API Gateway例子是Netfix API Gateway。Netflix流服务提供数百个不同的微服务,包括电视、机顶盒、智能手机、游戏系统、平板电脑等。起初,Netflix视图提供一个适用全场景的API。但是,他们发现这种形式不好用,因为涉及到各式各样的设备以及它们独特的需求。现在,他们采用一个API Gateway来提供容错性高的API,针对不同类型设备有相应代码。事实上,一个适配器处理一个请求平均要调用6到8个后端服务。Netflix API Gateway每天处理数十亿的请求。


    API Gateway的优点和缺点


    如你所料,采用API Gateway也是优缺点并存的。API Gateway的一个最大好处是封装应用内部结构。相比起来调用指定的服务,客户端直接跟gatway交互更简单点。API Gateway提供给每一个客户端一个特定API,这样减少了客户端与服务器端的通信次数,也简化了客户端代码。

    API Gateway也有一些缺点。它是一个高可用的组件,必须要开发、部署和管理。还有一个问题,它可能成为开发的一个瓶颈。开发者必须更新API Gateway来提供新服务提供点来支持新暴露的微服务。更新API Gateway时必须越轻量级越好。否则,开发者将因为更新Gateway而排队列。但是,除了这些缺点,对于大部分的应用,采用API Gateway的方式都是有效的。


    实现一个API Gateway


    既然我们已经知道了采用API Gateway的动机和优缺点,下面来看在设计它时需要考虑哪些事情。
    (1)性能和可扩展性
    只有少数公司需要处理像Netflix那样的规模,每天需要处理数十亿的请求。但是,对于大多数应用,API Gateway的性能和可扩展性也是非常重要的。因此,创建一个支持同步、非阻塞I/O的API Gateway是有意义的。已经有不同的技术可以用来实现一个可扩展的API Gateway。在JVM上,采用基于NIO技术的框架,如Netty,Vertx,Spring Reactor或者JBoss Undertow。Node.js是一个非JVM的流行平台,它是一个在Chrome的JavaScript引擎基础上建立的平台。一个可选的方案是NGINX Plus。NGINX Plus提供一个成熟的、可扩展的、高性能web服务器和反向代理,它们均容易部署、配置和二次开发。NGINX Plus可以管理授权、权限控制、负载均衡、缓存并提供应用健康检查和监控。
    (2)采用反应性编程模型
    对于有些请求,API Gateway可以通过直接路由请求到对应的后端服务上的方式来处理。对于另外一些请求,它需要调用多个后端服务并合并结果来处理。对于一些请求,例如产品最终页面请求,发给后端服务的请求是相互独立的。为了最小化响应时间,API Gateway应该并发的处理相互独立的请求。但是,有时候请求之间是有依赖的。API Gateway可能需要先通过授权服务来验证请求,然后在路由到后端服务。类似的,为了获得客户的产品愿望清单,需要先获取该用户的资料,然后返回清单上产品的信息。这样的一个API 组件是Netflix Video Grid。

    利用传统的同步回调方法来实现API合并的代码会使得你进入回调函数的噩梦中。这种代码将非常难度且难以维护。一个优雅的解决方案是采用反应性编程模式来实现。类似的反应抽象实现有Scala的Future,Java8的CompletableFuture和JavaScript的Promise。基于微软.Net平台的有Reactive Extensions(Rx)。Netflix为JVM环境创建了RxJava来使用他们的API Gateway。同样地,JavaScript平台有RxJS,可以在浏览器和Node.js平台上运行。采用反应编程方法可以帮助快速实现一个高效的API Gateway代码。
    (3)服务调用
    一个基于微服务的应用是一个分布式系统,并且必须采用线程间通信的机制。有两种线程间通信的方法。一种是采用异步机制,基于消息的方法。这类的实现方法有JMS和AMQP。另外的,例如Zeromq属于服务间直接通信。还有一种线程间通信采用同步机制,例如Thrift和HTTP。事实上一个系统会同时采用同步和异步两种机制。由于它的实现方式有很多种,因此API Gateway就需要支持多种通信方式。
    (4)服务发现
    API Gateway需要知道每一个微服务的IP和端口。在传统应用中,你可能会硬编码这些地址,但是在现在云基础的微服务应用中,这将是个简单的问题。基础服务通常会采用静态地址,可以采用操作系统环境变量来指定。但是,探测应用服务的地址就没那么容易了。应用服务通常动态分配地址和端口。同样的,由于扩展或者升级,服务的实例也会动态的改变。因此,API Gateway需要采用系统的服务发现机制,要么采用服务端发现,要么是客户端发现。后续的一篇文章将会更详细的介绍这部分。如果采用客户端发现服务,API Gateway必须要去查询服务注册处,也就是微服务实例地址的数据库。
    (5)处理部分失败
    在实现API Gateway过程中,另外一个需要考虑的问题就是部分失败。这个问题发生在分布式系统中当一个服务调用另外一个服务超时或者不可用的情况。API Gateway不应该被阻断并处于无限期等待下游服务的状态。但是,如何处理这种失败依赖于特定的场景和具体服务。例如,如果是在产品详情页的推荐服务模块无响应,那么API Gateway应该返回剩下的其他信息给用户,因为这些信息也是有用的。推荐部分可以返回空,也可以返回固定的顶部10个给用户。但是,如果是产品信息服务无响应,那么API Gateway就应该给客户端返回一个错误。

    在缓存有效的时候,API Gateway应该能够返回缓存。例如,由于产品价格变化并不频繁,API Gateway在价格服务不可用时应该返回缓存中的数值。这类数据可以由API Gateway自身来缓存,也可以由Redis或Memcached这类外部缓存实现。通过返回缓存数据或者默认数据,API Gateway来确保系统错误不影响到用户体验。

    Netflix Hystrix对于实现远程服务调用代码来说是一个非常好用的库。Hystrix记录那些超过预设定的极限值的调用。它实现了circuit break模式,使得可以将客户端从无响应服务的无尽等待中停止。如果一个服务的错误率超过预设值,Hystrix将中断服务,并且在一段时间内所有请求立刻失效。Hystrix可以为请求失败定义一个fallback操作,例如读取缓存或者返回默认值。如果你在用JVM,就应该考虑使用Hystrix。如果你采用的非JVM环境,那么应该考虑采用类似功能的库。


    展开全文
  • 微服务技术架构概述 euraka注册中心原理 服务调用工具rest与fegin SpringCloud调用服务原理剖析 SpringCloud实现服务负载均衡原理 使用ribbon客户端实现负载均衡 使用Zuul搭建服务网关解决跨域问题 搭建SpringCloud...
  • 本人正在找深圳Java实习工作,求大佬带飞 QQ:1172796094 如在文档中遇到什么问题请联系作者 —————————————————————————————————————— 服务消费者 获取服务列表 ...
  • 分布式、微服务架构盛行的今天,Spring Cloud越来越普及,你是否想学习这个框架,又发愁找不到完整的例子?本文将带领你从0开始搭建微服务环境,并且集成网关、熔断器,达到各服务节点的负载均衡,万能脚手架!
  • 原文链接:ewanvalentine.io,翻译已获作者 Ewan Valentine ...《Golang 微服务教程》分为 10 篇,总结微服务开发、测试到部署的完整过程。 本节先介绍微服务的基础概念、术语,再创建我们的第一个微服务 consign...
  • 19年录制Zookeeper、Dubbo视频教程 微服务教程分布式教程 SpringBoot教程整合 ...
  • 疯狂Spring Cloud微服务教程 从事十多年的Java EE企业应用开...
  • Docker 微服务教程

    2018-03-31 09:12:29
    Docker 是一个容器工具,提供虚拟环境。很多人认为,它改变了我们对软件的认识。...这正是微服务(microservices)的思想:软件把任务外包出去,让各种外部服务完成这些任务,软件本身只是底层服务的调度中...
  • 疯狂Spring Cloud微服务教程

    千人学习 2017-11-06 09:11:17
    以Spring Cloud为基础,深入讲解微服务开发的相关框架,包括服务管理框架Eureka、负载均衡框架Ribbon、服务客户端Feign、容错框架Hystrix、消息框架Stream等。
  • 课程版本:Apache Shiro零基础到高级实战是2019年6月录制,采用官方最新1.4版本,分为10章38集 核心内容: ... 1)从零基础讲解Shiro框架到高级实战,整合SpringBoot2.x新版本;... 2)详细讲解Shiro架构图包括 ...
  • 微服务教程-使用Spring Cloud
  • 38集19年Shiro视频教程Springboot教程整合Shiro 权限教程微服务教程 ...
  • Golang 微服务教程

    2020-03-26 23:27:54
    《Golang 微服务教程》分为 10 篇,总结微服务开发、测试到部署的完整过程。 本节先介绍微服务的基础概念、术语,再创建我们的第一个微服务 consignment-service 的简洁版。在接下来的第 2~10 节文章中,我们会陆续...
  • Spring Cloud微服务教程(一) 文章目录 Spring Cloud微服务教程(一) 1.教程大纲 2.统一开发环境 3.微服务架构 3.1.单体架构 3.2.单体架构存在的问题 3.3.什么是微服务? 3.4.微服务架构的特征 3.5.微服务架构示例 4....
  • 译文链接:wuYin/blog原文链接:ewanvalentine.io,翻译已获作者 Ewan Valentine 授权。...在上一篇中,我们使用 gRPC 初步实现了我们的微服务,本节将 Docker 化该微服务并引入 go-micro 框架代替 gRPC...
  • Golang微服务教程

    2019-05-26 16:45:41
    转自:https://segmentfault.com/a/1190000015135650?utm_campaign=studygolang.com&... 前言 系列概览 《Golang 微服务教程》分为 10 篇,总结微服务开发、测试到部署的完整过程。 本节先介绍微服务...
  • 转载请标明出处: ... 来自昌杰的攻城狮之路 ...Dubbo教程 前置篇:Linux下安装java JDK & 部署Zookeeper 前置篇:Linux下安装Tomcat 8.5 讲解篇:Dubbo深度详解,及结合Zookeeper、SSM的RPC实战 ...

空空如也

1 2 3 4 5 ... 20
收藏数 20,202
精华内容 8,080
关键字:

微服务教程