精华内容
下载资源
问答
  • SpringCloud+Vue微服务教程与实战(1)--全新的开始
    2020-07-30 18:21:08

    点此查看全部文字教程、视频教程、源代码

    1. 背景

    之前已经讲过SSM完整的教程,我个人觉得是相当不错的,附上地址:Spring+SpringMVC+MyBatis 系列教程50篇

    SSM之后,又精心编写了SpringBoot教程,附上地址:Spring Boot系列教程25篇

    然后呢,是时候开启SpringCloud+Vue微服务的教程与实战系列了,先讲一下Spring Cloud教程部分、然后讲一下Vue教程部分、最后实现一个SpringCloud+Vue的完整实例。

    2. 微服务架构的优缺点

    微服务架构,与传统的单体应用相比,优缺点都比较明显,尤为注意的是不要盲目的上微服务架构。

    • 复杂度。由于微服务是由诸多服务组成,其复杂度要远远超过单体应用,所以一般小项目不建议采用微服务架构。
    • 可靠性。由于微服务下各种组件都可以部署多套,从而形成高可用的集群,所以可靠性一般高于单体应用的。
    • 性能提升空间。当用户量急剧上升时,微服务架构可以提供更广阔的性能提升空间。但是这非常依赖开发人员的技术水平,所以说提升空间是比较大的,但是弄不好可能还不如单体应用性能好。

    总之,微服务更加复杂,但是如果做好了,各方面都能有一个比较大的提升。

    3. 实现技术

    常见的是Dubbo和SpringCloud,当然完全可以自己封装几个服务。只要服务之间互相有调用关系,我们也可以认为这是一个微服务系统。

    个人建议还是采用SpringCloud,依赖于Spring生态,可选择的组件、解决方案比较多,遇到问题也容易找到资料。

    4. 开发环境

    1. JDK1.8
    2. Maven
    3. MySQL5.7
    4. Eclipse或者IDEA
    5. Lombok插件
    6. NPM
    7. VSCode

    这些工具的安装之前已经讲过很多次了,此处不再赘述。

    5. 小结

    开整。

    更多相关内容
  • 微服务教程

    2019-01-21 08:08:49
    微服务搭建教程,欢迎大家下载。跟着文档一步一步搭建就可以。
  • docker微服务教程

    2019-01-02 14:09:25
    docker的教程,详细讲述docker的使用,省去Linux下载,安装配置的麻烦,直接使用容器就好,你值得拥有 (●'◡'●)
  • 以Spring Cloud为基础,深入讲解微服务开发的相关框架,包括服务管理框架Eureka、负载均衡框架Ribbon、服务客户端Feign、容错框架Hystrix、消息框架Stream等。
  • 这正是微服务(microservices)的思想:软件把任务外包出去,让各种外部服务完成这些任务,软件本身只是底层服务的调度中心和组装层。微服务很适合用Docker容器实现,每个容器承载一个服务。一台计算机同时运行多个...
  • 微服务教程源码微服务教程源码
  • 38集19年Shiro视频教程Springboot教程整合Shiro 权限教程微服务教程
  • 微服务技术架构概述 euraka注册中心原理 服务调用工具rest与fegin SpringCloud调用服务原理剖析 SpringCloud实现服务负载均衡原理 使用ribbon客户端实现负载均衡 使用Zuul搭建服务网关解决跨域问题 搭建SpringCloud...
  • java Spring Cloud微服务教程_all.zip Spring Cloud Eureka Spring Cloud Consumer,Provider Spring Cloud Hystrix Spring Cloud Feign Spring CLoud Stream Spring Cloud Config Spring Cloud Bus
  • SFG的微服务教程(Udemy) 第5节:Spring Boot RestTemplate 54. Apache客户端请求记录 为Apache Http启用调试logging.level.org.apache.http=debug 运行集成测试 启动ArtSfgMsscBreweryApplication 运行测试...
  • SpringCloud与微服务教程(Eureka、Ribbon、Feign、Hystrix、Turbine、API Gateway、Zuul、Sidecar),永久链接,大小为23.38G,内含视频教程,示例代码,全是干粮,实在好货。
  • spring cloud 微服务 教程 视频 主要包含 服务发现——Netflix Eureka 客服端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关——Netflix Zuul 分布式配置——Spring Cloud Config
  • 什么是微服务二、什么是protobuf2.1优点2.2缺点三.Protobuf安装步骤四.加入golang的支持1.获取 proto包2.安装protoc-gen-go插件五.demo1.编写test.proto测试类2.编译 一.什么是微服务 据说,早在2011年5月,在威尼斯...

    一.什么是微服务

    据说,早在2011年5月,在威尼斯附近的软件架构师讨论会上,就有人提出了微服务架构设计的概念,用它来描述与会者所见的一种通用的架构设计风格。时隔一年之后,在同一个讨论会上,大家决定将这种架构设计风格用微服务架构来表示。

    起初,对微服务的概念,没有一个明确的定义,大家只能从各自的角度说出了微服务的理解和看法。
    有人把微服务理解为一种细粒度SOA(service-oriented Architecture,面向服务架构),一种轻量级的组件化的小型SOA。 在2014年3月,詹姆斯·刘易斯(James Lewis)与马丁·福勒(Martin Fowler)所发表的一篇博客中,总结了微服务架构设计的一些共同特点,这应该是一个对微服务比较全面的描述。

    这篇文章中认为:“简而言之,微服务架构风格是将单个应用程序作为一组小型服务开发的方法,每个服务程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务功能构建的。可以通过全自动部署机器独立部署。这些服务器可以用不同的编程语言编写,使用不同的数据存储技术,并尽量不用集中式方式进行管理“

    	原文链接 https://martinfowler.com/articles/microservices.html
    

    二、什么是protobuf

    protobuf是google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式。
    你可以理解为类似json的传输格式,但是它比json传输更快,体积更小,也更安全。

    protobuf是后起之秀,是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。

    2.1优点

    相对于其它protobuf更具有优势
    1:序列化后体积相比Json和XML很小,适合网络传输
    2:支持跨平台多语言
    3:消息格式升级和兼容性还不错
    4:序列化反序列化速度很快,快于Json的处理速速

    2.2缺点

    Protobuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。
    XML 已经成为多种行业标准的编写工具,Protobuf 只是 Google 公司内部使用的工具,在通用性上还差很多。 由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。
    另外,由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容。

    三.Protobuf安装步骤

    Linux平台

    #下载 protoBuf: 
    $ git clone https://github.com/protocolbuffers/protobuf.git 123
    #安装依赖库 
    $ sudo apt-get install autoconf automake libtool curl make g++ unzip libffi- dev -y 
    #安装
     $ cd protobuf/ 
     $ ./autogen.sh 
     $ ./configure 
     $ make 
     $ sudo make install $ sudo ldconfig 
     # 刷新共享库 很重要的一步啊 #安装的时候会比较卡 #成功后需要使用命令测试 
     $ protoc –h
    

    windows平台
    1.下载安装文件
    https://github.com/protocolbuffers/protobuf/releases/tag/v3.10.0

    2.解压到任意目录

    3.配置环境变量

    将上一步解压出来的目录/bin(即protoc.exe所在的目录)添加到环境变量中
    

    4.检查

    cmd输入protoc查看是否安装成功
    

    四.加入golang的支持

    1.获取 proto包

    #Go语言的proto API接口
     $ go get -v -u github.com/golang/protobuf/proto
    

    2.安装protoc-gen-go插件

    #安装 
    $ go get -v -u github.com/golang/protobuf/protoc-gen-go
    #编译 
    $ cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/ 
    $ go build
    #将生成的 protoc-gen-go可执行文件,放在/bin目录下 
    $ sudo cp protoc-gen-go /bin/
    

    五.demo

    1.编写test.proto测试类

    syntax = "proto3";
    package myproto;
    message Test {
      string name = 1;
      int32 stature = 2 ;
      repeated int64 weight = 3;
      string motto = 4;
    }
    

    2.编译

    进入proto所在目录,执行以下命令即可编译成go文件

    protoc --go_out=./ *.proto
    
    展开全文
  • Spring Cloud微服务教程(一) 文章目录 Spring Cloud微服务教程(一) 1.教程大纲 2.统一开发环境 3.微服务架构 3.1.单体架构 3.2.单体架构存在的问题 3.3.什么是微服务? 3.4.微服务架构的特征 3.5.微服务架构示例 4....

    Spring Cloud微服务教程-第一篇

    1.教程大纲
    2.统一开发环境
    3.微服务架构
    4.Spring Cloud简介
    5.使用 Spring Boot 实现微服务
    6.Spring Cloud快速入门

    1.教程大纲
    统一开发环境
    了解微服务架构
    了解Spring Cloud
    Spring Cloud快速入门
    Eureka服务注册中心
    使用Ribbon实现负载均衡
    使用Hystrix实现容错
    2.统一开发环境
    JDK: 1.8
    IDE: IntelliJ IDEA
    Maven:3.3.9
    OS: Windows 10 10.0
    Springboot版本:2.0+
    3.微服务架构
    目前微服务是非常火的架构或者说概念,也是在构建大型互联网项目时采用的架构方式。

    3.1.单体架构
    单体架构,是指将开发好的项目打成war包,然后发布到tomcat等容器中的应用。

    假设你正准备开发一款与Uber和滴滴竞争的出租车调度软件,经过初步会议和需求分析,你可能会手动或者使用基于Spring Boot、Play或者Maven的生成器开始这个新项目,它的六边形架构是模块化的
    应用核心是业务逻辑,由定义服务、领域对象和事件的模块完成。围绕着核心的是与外界打交道的适配器。适配器包括数据库访问组件、生产和处理消息的消息组件,以及提供API或者UI访问支持的web模块等。

    尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用。具体的格式依赖于应用语言和框架。例如,许多Java应用会被打包为WAR格式,部署在Tomcat或者Jetty上,而另外一些Java应用会被打包成自包含的JAR格式,类似的,Rails和Node.js会被打包成层级目录。

    这种应用开发风格很常见,因为IDE和其它工具都擅长开发一个简单应用,这类应用也很易于调试,只需要简单运行此应用,用Selenium链接UI就可以完成端到端测试。单体式应用也易于部署,只需要把打包应用拷贝到服务器端,通过在负载均衡器后端运行多个拷贝就可以轻松实现应用扩展。在早期这类应用运行的很好。

    3.2.单体架构存在的问题
    在这里插入图片描述
    在这里插入图片描述
    如何解决以上问题呢? – 使用微服务架构。使得应用由重变轻。

    3.3.什么是微服务?
    在这里插入图片描述
    微服务架构的特征
    在这里插入图片描述
    3.5.微服务架构示例
    在这里插入图片描述
    每一个应用功能区都使用微服务完成。

    4.Spring Cloud简介
    4.1.简介
    Spring Cloud项目的官方网址:
    http://projects.spring.io/spring-cloud/
    4.2.Spring Cloud子项目
    在这里插入图片描述
    4.3.版本说明
    在这里插入图片描述
    4.4.Spring Cloud框架特点
    在这里插入图片描述
    5.使用 Spring Boot 实现微服务
    在正式学习Spring Cloud之前我们先使用Spring Boot实现一个微服务。

    业务非常简单:
    1、商品微服务:通过商品id查询商品的服务;
    2、订单微服务:创建订单时通时,通过调用商品的微服务进行查询商品数据;

    图示:在这里插入图片描述
    说明:
    1、对于商品微服务而言,商品微服务是服务的提供者,订单微服务是服务的消费者;
    2、对于订单微服务而言,订单微服务是服务的提供者,人是服务的消费者。

    5.1.实现商品微服务
    5.1.1.创建maven工程
    地址git:
    5.1.2.导入依赖
    重点是导入Spring Boot的依赖:

    <?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.zpc.microservice</groupId>
        <artifactId>microservice-item</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <!-- 资源文件拷贝插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <!-- java编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        </project>
    
    5.1.3.创建实体Item
    
    package com.zpc.item.entity;
    
    public class Item {
    
        private Long id;
    
        private String title;
    
        private String pic;
    
        private String desc;
    
        private Long price;
    
        public Item(){}
    
        public Item(long id, String title, String pic, String desc, Long price) {
            this.id=id;
            this.title=title;
            this.pic=pic;
            this.desc=desc;
            this.price=price;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getPic() {
            return pic;
        }
    
        public void setPic(String pic) {
            this.pic = pic;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    
        public Long getPrice() {
            return price;
        }
    
        public void setPrice(Long price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Item [id=" + id + ", title=" + title + ", pic=" + pic + ", desc=" + desc + ", price=" + price + "]";
        }
    
    }
    

    5.1.4.编写ItemService
    编写ItemService用于实现具体的商品查询逻辑,为了演示方便,我们并不真正的连接数据库,而是做模拟实现。

    package com.zpc.item.service;
    import com.zpc.item.entity.Item;
    import org.springframework.stereotype.Service;
    import java.util.HashMap;
    import java.util.Map;
    
    @Service
    public class ItemService {
    
        private static final Map<Long, Item> ITEM_MAP = new HashMap<Long, Item>();
    
        static {// 准备一些静态数据,模拟数据库
            ITEM_MAP.put(1L, new Item(1L, "商品1", "http://图片1", "商品描述1", 1000L));
            ITEM_MAP.put(2L, new Item(2L, "商品2", "http://图片2", "商品描述2", 2000L));
            ITEM_MAP.put(3L, new Item(3L, "商品3", "http://图片3", "商品描述3", 3000L));
            ITEM_MAP.put(4L, new Item(4L, "商品4", "http://图片4", "商品描述4", 4000L));
            ITEM_MAP.put(5L, new Item(5L, "商品5", "http://图片5", "商品描述5", 5000L));
            ITEM_MAP.put(6L, new Item(6L, "商品6", "http://图片6", "商品描述6", 6000L));
            ITEM_MAP.put(7L, new Item(7L, "商品7", "http://图片7", "商品描述7", 7000L));
            ITEM_MAP.put(8L, new Item(8L, "商品8", "http://图片8", "商品描述8", 8000L));
            ITEM_MAP.put(8L, new Item(9L, "商品9", "http://图片9", "商品描述9", 9000L));
            ITEM_MAP.put(8L, new Item(10L, "商品10", "http://图片10", "商品描述10", 10000L));
        }
    
        /**
         * 模拟实现商品查询
         *
         * @param id
         * @return
         */
        public Item queryItemById(Long id) {
            return ITEM_MAP.get(id);
        }
    
    }
    

    5.1.5.编写ItemController

    package com.zpc.item.controller;
    
    import com.zpc.item.entity.Item;
    import com.zpc.item.service.ItemService;
    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.RestController;
    
    @RestController
    public class ItemController {
    
        @Autowired
        private ItemService itemService;
    
        /**
         * 对外提供接口服务,查询商品信息
         *
         * @param id
         * @return
         */
        @GetMapping(value = "item/{id}")
        public Item queryItemById(@PathVariable("id") Long id) {
            return this.itemService.queryItemById(id);
        }
    
    }
    

    @RestController注解的说明:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Controller
    @ResponseBody
    public @interface RestController {
    
       /**
        * The value may indicate a suggestion for a logical component name,
        * to be turned into a Spring bean in case of an autodetected component.
        * @return the suggested component name, if any (or empty String otherwise)
        * @since 4.0.1
        */
       @AliasFor(annotation = Controller.class)
       String value() default "";
    
    }
    

    从源码可以看出,这是一个组合注解,组合了@Controller和@Response注解。相当于我们同时写了这2个注解。
    @GetMapping注解是@RequestMapping(method = RequestMethod.GET)简写方式。其功能都是一样的。

    同理还有其它注解:@PostMapping @PutMapping @ResttMapping等
    5.1.6.编写程序入口

    package com.zpc.item.runner;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * @author Evan
     */
    
    @SpringBootApplication//申明这是一个Spring Boot项目
    @ComponentScan(basePackages = {"com.zpc.item.controller","com.zpc.item.service"})//手动指定bean组件扫描范围
    public class ItemApp {
        public static void main(String[] args) {
            SpringApplication.run(ItemApp.class, args);
        }
    }
    

    5.1.7.创建application.yml配置文件
    Spring Boot以及Spring Cloud项目支持yml和properties格式的配置文件。

    yml格式是YAML(Yet Another Markup Language)编写的格式,YAML和properties格式的文件是可以相互转化的。如:

    server:
      port: 8081 #服务端口
    

    等价于properties文件的配置:
    server.port=8081

    配置文件的示例:

    server:
      port: 8081 #服务端口
    

    5.1.8.启动程序测试
    在这里插入图片描述
    5.2.实现订单微服务
    5.2.1.创建工程
    地址git:
    5.2.2.导入依赖

    <?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.zpc.microservice</groupId>
        <artifactId>microservice-item</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <!-- 资源文件拷贝插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <!-- java编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        </project>
    

    5.2.3.创建订单Order实体

    package com.zpc.order.entity;
    
    import java.util.Date;
    import java.util.List;
    
    public class Order {
    
        private String orderId;
    
        private Long userId;
    
        private Date createDate;
    
        private Date updateDate;
    
        private List<OrderDetail> orderDetails;
    
        public Order() {
    
        }
    
        public Order(String orderId, Long userId, Date createDate, Date updateDate) {
            this.orderId = orderId;
            this.userId = userId;
            this.createDate = createDate;
            this.updateDate = updateDate;
        }
    
        public String getOrderId() {
            return orderId;
        }
    
        public void setOrderId(String orderId) {
            this.orderId = orderId;
        }
    
        public Long getUserId() {
            return userId;
        }
    
        public void setUserId(Long userId) {
            this.userId = userId;
        }
    
        public Date getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
    
        public Date getUpdateDate() {
            return updateDate;
        }
    
        public void setUpdateDate(Date updateDate) {
            this.updateDate = updateDate;
        }
    
    
        public List<OrderDetail> getOrderDetails() {
            return orderDetails;
        }
    
        public void setOrderDetails(List<OrderDetail> orderDetails) {
            this.orderDetails = orderDetails;
        }
    
        @Override
        public String toString() {
            return "Order [orderId=" + orderId + ", userId=" + userId
                    + ", createDate=" + createDate + ", updateDate=" + updateDate
                    + "]";
        }}
    

    5.2.4.创建订单详情OrderDetail实体
    订单与订单详情是一对多的关系。

    package com.zpc.order.entity;
    
    public class OrderDetail {
    
        private String orderId;
    
        private Item item = new Item();
    
        public OrderDetail() {
    
        }
    
        public OrderDetail(String orderId, Item item) {
            this.orderId = orderId;
            this.item = item;
        }
    
        public String getOrderId() {
            return orderId;
        }
    
        public void setOrderId(String orderId) {
            this.orderId = orderId;
        }
    
        public Item getItem() {
            return item;
        }
    
        public void setItem(Item item) {
            this.item = item;
        }
    
        @Override
        public String toString() {
            return "OrderDetail [orderId=" + orderId + ", item=" + item + "]";
        }
    
    }
    

    5.2.5.将商品微服务项目中的Item类拷贝到当前工程
    在这里插入图片描述
    5.2.6.编写OrderService
    该Service实现的根据订单Id查询订单的服务,为了方便测试,我们将构造数据实现,不采用查询数据库的方式。

    package com.zpc.order.service;
    
    import com.zpc.order.entity.Item;
    import com.zpc.order.entity.Order;
    import com.zpc.order.entity.OrderDetail;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.*;
    
    @Service
    public class OrderService {
    
        private static final Map<String, Order> ORDER_DATA = new HashMap<String, Order>();
    
        static {
            // 模拟数据库,构造测试数据
            Order order = new Order();
            order.setOrderId("201810300001");
            order.setCreateDate(new Date());
            order.setUpdateDate(order.getCreateDate());
            order.setUserId(1L);
            List<OrderDetail> orderDetails = new ArrayList<OrderDetail>();
    
            Item item = new Item();// 此处并没有商品的数据,只是保存了商品ID,需要调用商品微服务获取
            item.setId(1L);
            orderDetails.add(new OrderDetail(order.getOrderId(), item));
    
            item = new Item(); // 构造第二个商品数据
            item.setId(2L);
            orderDetails.add(new OrderDetail(order.getOrderId(), item));
    
            order.setOrderDetails(orderDetails);
    
            ORDER_DATA.put(order.getOrderId(), order);
        }
    
        @Autowired
        private ItemService itemService;
    
        /**
         * 根据订单id查询订单数据
         *
         * @param orderId
         * @return
         */
        public Order queryOrderById(String orderId) {
            Order order = ORDER_DATA.get(orderId);
            if (null == order) {
                return null;
            }
            List<OrderDetail> orderDetails = order.getOrderDetails();
            for (OrderDetail orderDetail : orderDetails) {
                // 通过商品微服务查询商品详细数据
                Item item = this.itemService.queryItemById(orderDetail.getItem()
                        .getId());
                if (null == item) {
                    continue;
                }
                orderDetail.setItem(item);
            }
    
            return order;
        }
    
    }
    

    5.2.7.实现ItemService

    package com.zpc.order.service;
    
    
    import com.zpc.order.entity.Item;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    @Service
    public class ItemService {
    
        // Spring框架对RESTful方式的http请求做了封装,来简化操作
        @Autowired
        private RestTemplate restTemplate;
    
        public Item queryItemById(Long id) {
            return this.restTemplate.getForObject("http://127.0.0.1:8081/item/"
                    + id, Item.class);
        }
    
    }
    5.2.8.编写OrderController
    package com.zpc.order.controller;
    
    import com.zpc.order.entity.Order;
    import com.zpc.order.service.OrderService;
    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.RestController;
    
    @RestController
    public class OrderController {
        @Autowired
        private OrderService orderService;
    
        @GetMapping(value = "order/{orderId}")
        public Order queryOrderById(@PathVariable("orderId") String orderId) {
            return this.orderService.queryOrderById(orderId);
        }
    }
    

    5.2.9.编写程序入口

    package com.zpc.order.runner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * @author Evan
     */
    @SpringBootApplication//申明这是一个Spring Boot项目
    @ComponentScan(basePackages = {"com.zpc.order.controller", "com.zpc.order.service"})//手动指定bean扫描范围
    public class OrderApp {
        public static void main(String[] args) {
            SpringApplication.run(OrderApp.class, args);
        }
    
        /**
         * 向Spring容器中定义RestTemplate对象
         * @return
         */
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    

    5.2.10.编写application.yml配置文件

    server:
      port: 8082 #服务端口
    

    5.2.11.启动测试
    在这里插入图片描述
    5.3.添加okHttp的支持
    okhttp是一个封装URL,比HttpClient更友好易用的工具。看个人习惯,HttpClient用的人也很多。
    RestTemplate底层默认使用的jdk的标准实现,如果我们想让RestTemplate的底层使用okhttp,非常简单:
    1、添加okhttp依赖

    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>3.9.0</version>
    </dependency>
    

    2、设置requestFactory
    return new RestTemplate(new OkHttp3ClientHttpRequestFactory());

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

    在这里插入图片描述
    查看 http://localhost:8082/order/201810300001 测试结果是一样的。
    5.4.解决订单系统中的url硬编码问题

    1. 通过以上的测试我们发现,在订单系统中要调用商品微服务中的查询接口来获取数据,在订单微服务中将url硬编码到代码中,这样显然不好,因为,运行环境一旦发生变化这个url地址将不可用。
    2. 如何解决呢?
      解决方案:将url地址写入到application.yml配置文件中。

    实现:
    修改application.yml文件:

    server:
      port: 8082 #服务端口
    myspcloud:
      item:
        url: http://127.0.0.1:8081/item/
    

    修改ItemService中的实现:

    @Service
    public class ItemService {
    
        // Spring框架对RESTful方式的http请求做了封装,来简化操作
        @Autowired
        private RestTemplate restTemplate;
    
        @Value("${myspcloud.item.url}")
        private String itemUrl;
    
        public Item queryItemById(Long id) {
            return this.restTemplate.getForObject(itemUrl
                    + id, Item.class);
        }
    
    }
    

    5.5.继续优化解决硬编码的问题
    在SpringBoot中使用@ConfigurationProperties注解可以非常简单的将配置文件中的值映射成对象。
    第一步,创建ItemProperties类:

    package com.zpc.order.properties;
    
    public class ItemProperties {
        private String url;
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
    }
    

    第二步,创建OrderProperties类:

    package com.zpc.order.properties;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    /**
     * 以myspcloud开头的配置被匹配到
     * @author Evan
     */
    @Component
    @ConfigurationProperties(prefix="myspcloud")
    public class OrderProperties {
    
        private ItemProperties item = new ItemProperties();
    
        public ItemProperties getItem() {
            return item;
        }
    
        public void setItem(ItemProperties item) {
            this.item = item;
        }
    }
    

    第三步,在Itemservice中注入该对象:

    @Service
    public class ItemService {
    
        // Spring框架对RESTful方式的http请求做了封装,来简化操作
        @Autowired
        private RestTemplate restTemplate;
    
        //@Value("${myspcloud.item.url}")
        //private String itemUrl;
    
        @Autowired
        OrderProperties orderProperties;
    
        public Item queryItemById(Long id) {
            return this.restTemplate.getForObject(orderProperties.getItem().getUrl()
                    + id, Item.class);
        }
    

    第四步,启动类中增加bean扫描路径

    @ComponentScan(basePackages = {"com.zpc.order.controller","com.zpc.order.service","com.zpc.order.properties"})//
    手动指定bean扫描范围
    

    可以看出,这种解决方案比第一种好很多,更加的方便的。
    6.Spring Cloud快速入门
    6.1.分析硬编码的问题
    通过前面5.4、5.5的实现,我们视乎已经解决了url硬编码的问题,但是我们想想:
    1、如果商品微服务的ip地址发生了变更,订单微服务中的配置文件也需要跟着修改
    2、如果商品微服务有多个,那么在订单微服务中又该如何写地址?

    那应该怎么解决呢? – 通过服务注册、发现的机制来完成。

    6.2.微服务注册与发现
    在这里插入图片描述
    由上图可以看出:
    1、服务提供者将服务注册到注册中心
    2、服务消费者通过注册中心查找服务
    3、查找到服务后进行调用(这里就是无需硬编码url的解决方案)
    4、服务的消费者与服务注册中心保持心跳连接,一旦服务提供者的地址发生变更时,注册中心会通知服务消费者

    6.3.注册中心:Eureka
    Spring Cloud提供了多种注册中心的支持,如:Eureka、consul、ZooKeeper等。Eureka已经闭源了。本教程第二篇也会介绍使用其它两种方式作为注册中心。ureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
    6.3.1.原理
    在这里插入图片描述
    Eureka包含两个组件:Eureka Server和Eureka Client。
    Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
    Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
    在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
    Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。
    6.3.2.编写Eureka Server
    第一步:创建Maven工程:
    git代码地址:
    第二步,导入依赖:
    这里需要导入Spring Cloud的管理依赖。

    <?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.zpc.springcloud.eureka</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
        <dependencyManagement>
            <dependencies>
                <!-- 导入Spring Cloud的依赖管理 -->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
        	<!--springboot 整合eureka服务端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    第三步,编写程序启动类:

    package com.zpc.springcloud.eureka;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    /**
     * Eureka注册中心
     */
    @SpringBootApplication
    @EnableEurekaServer //申明这是一个Eureka服务
    public class AppEureka {
    
       public static void main(String[] args) {
          SpringApplication.run(AppEureka.class, args);
       }
    }
    

    第四步,编写application.yml配置文件:

    ###服务端口号
    server:
      port: 8100
    
    ###服务名称
    spring:
      application:
        name: app-eureka-center
    
    eureka:
      instance:
        #注册中心地址
        hostname: 127.0.0.1
    ###客户端调用地址
      client:
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:8100/eureka/
    ###是否将自己注册到Eureka服务中,因为该应用本身就是注册中心,不需要再注册自己(集群的时候为true)
        register-with-eureka: false
    ###是否从Eureka中获取注册信息,因为自己为注册中心,不会在该应用中的检索服务信息
        fetch-registry: false
    

    第五步,启动程序做测试:
    在这里插入图片描述
    6.4.将商品微服务注册到Eureka
    接下来,我们需要将商品的微服务注册到Eureka服务中。

    第一步:修改pom文件,引入Spring Cloud的管理依赖以及eureka服务依赖。

    <?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.zpc.microservice</groupId>
        <artifactId>microservice-item</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--springboot 整合eureka客户端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <!-- 资源文件拷贝插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <!-- java编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    第二步,修改application.yml配置文件:

    ###服务端口号(本身是一个web项目)
    server:
      port: 8081
    ###起个名字作为服务名称(该服务注册到eureka注册中心的名称,比如商品服务)
    spring:
        application:
            name: app-item
    ###服务注册到eureka注册中心的地址
    eureka:
      client:
        service-url:
               defaultZone: http://127.0.0.1:8100/eureka
    ###因为该应用为服务提供者,是eureka的一个客户端,需要注册到注册中心
        register-with-eureka: true
    ###是否需要从eureka上检索服务
        fetch-registry: true
    

    第三步,修改启动类,增加@EnableEurekaClient 注解:

    package com.zpc.item.runner;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * @author Evan
     */
    //申明这是一个Spring Boot项目
    @SpringBootApplication
    @EnableEurekaClient
    @ComponentScan(basePackages = {"com.zpc.item.controller","com.zpc.item.service"})
    public class ItemApp {
        public static void main(String[] args) {
            SpringApplication.run(ItemApp.class, args);
        }
    
    }
    

    第四步,启动测试:
    在这里插入图片描述
    至此,我们已经将自己的微服务注册到Eureka server中了。

    6.5.订单系统从Eureka中发现商品服务
    之前我们在订单系统中是将商品微服务的地址进行了硬编码,现在,由于已经将商品服务注册到Eureka中,所以,只需要从Eureka中发现服务即可。

    第一步,在订单系统中添加依赖:

    <?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.zpc.microservice</groupId>
        <artifactId>microservice-order</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--springboot 整合eureka客户端-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>3.9.0</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <!-- 资源文件拷贝插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <!-- java编译插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    第二步,修改application.yml配置文件:

    server:
      port: 8082 #服务端口
    myspcloud:
      item:
        url: http://127.0.0.1:8081/item/
    ###起个名字作为服务名称(该服务注册到eureka注册中心的名称,比如订单服务)
    spring:
        application:
            name: app-order
    ###服务注册到eureka注册中心的地址
    eureka:
      client:
        service-url:
               defaultZone: http://127.0.0.1:8100/eureka
    ###因为该应用为服务提供者,是eureka的一个客户端,需要注册到注册中心
        register-with-eureka: true
    ###是否需要从eureka上检索服务
        fetch-registry: true
    

    第三步,修改ItemService的实现逻辑:

    package com.zpc.order.service;
    import com.zpc.order.entity.Item;
    import com.zpc.order.properties.OrderProperties;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    @Service
    public class ItemService {
    
        // Spring框架对RESTful方式的http请求做了封装,来简化操作
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        OrderProperties orderProperties;
    
        public Item queryItemById(Long id) {
    
            // 该方法走eureka注册中心调用(去注册中心根据app-item查找服务,这种方式必须先开启负载均衡@LoadBalanced)
            String itemUrl = "http://app-item/item/{id}";
            Item result = restTemplate.getForObject(itemUrl, Item.class, id);
            System.out.println("订单系统调用商品服务,result:" + result);
            return result;
        }
    }
    

    第四步,在启动类中添加@EnableEurekaClient注解 ,获取RestTemplate的方法上加 @LoadBalanced注解

    package com.zpc.order.runner;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * @author Evan
     */
    
    @SpringBootApplication//申明这是一个Spring Boot项目
    @EnableEurekaClient
    @ComponentScan(basePackages = {"com.zpc.order.controller", "com.zpc.order.service","com.zpc.order.properties"})//手动指定bean扫描范围
    public class OrderApp {
        public static void main(String[] args) {
            SpringApplication.run(OrderApp.class, args);
        }
    
        /**
         * 向Spring容器中定义RestTemplate对象
         * @return
         */
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
        }
    
    }
    

    第五步,启动测试(此时有3个应用:Eureka注册中心、Item服务、order服务)
    在这里插入图片描述
    在注册中心http://localhost:8100看到有2个客户端。

    展开全文
  • 目前业界最流行的微服务架构正在或者已被各种规模的互联网公司广泛接受和认可,业已成为互联网开发人员必备技术。无论是互联网、云计算还是大数据Java平台已成为全栈的生态体系,其重要性几乎不可替代。Spring Boot...
  • 微服务教程-使用Spring Cloud
  • 微服务入门教程

    2018-06-02 14:22:04
    微服务入门教程微服务入门教程微服务入门教程微服务入门教程 微服务入门教程微服务入门教程微服务入门教程微服务入门教程
  • 简单的说Micro是一个微服务框架 它默认实现了consul作为服务发现,通过http、protobuf、进行通信。 二.Micro安装步骤 1.下载 先把所有的依赖库都下载一遍 go get -u -v github.com/go-log/log go get -u -v github...
  • Golang 微服务教程

    2020-03-26 23:27:54
    《Golang 微服务教程》分为 10 篇,总结微服务开发、测试到部署的完整过程。 本节先介绍微服务的基础概念、术语,再创建我们的第一个微服务 consignment-service 的简洁版。在接下来的第 2~10 节文章中,我们会陆续...
  • SpringCloud微服务笔记

    2020-01-03 20:59:58
    ## 微服务概述 [马丁福勒微服务论文]: https://martinfowler.com/articles/microservices.html ### 什么是微服务 - 目前的微服务并没有一个统一的标准,一般是以业务来划分 - 将传统的一站式应用,拆分成一个个...
  •  从最初的spring、strtus2、hibernate架构,到spring、springmvc、mybatis,到现在的微服务架构,这些技术的发展对我们开发者而言,最明显的改变就是让我的开发越来越简便。  学校所学的技术无非就是Java基础,到...
  • 一、微服务的注册与发现(Eureka) 1.eureka server gradle引入 注解启动 配置部分 ...二、微服务的消费者 1.Apache HttpClient gradle引入 代码调用 2.Ribbon gradle引入 代码调用 ...
  • 译文链接:wuYin/blog原文链接:...在上节中,我们使用 JWT 在微服务之间进行了用户的认证。在本节中,我们将使用 go-micro 结合 nats 插件来完成用户创建事件的发布与订阅。 正如前几节所说,go-micro ...
  • 微服务,已经成为了互联网行业的最低的门槛,如果不能熟练的掌握微服务,我想无论是升级加薪,还是进大厂,都是很困难的,接下来跟我一起学习微服务,一步一步的大好坚实的基础,为美好的未来做铺垫。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,314
精华内容 12,925
关键字:

微服务教程

友情链接: harish.zip