1        Spring Cloud简介

1.1             简介

Spring Cloud项目的官方网址:https://projects.spring.io/spring-cloud/

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

1.2             子项目介绍

子项目名称

描述

Spring CloudAws

用于简化整合Amazon Web Service的组件

Spring Cloud Bus

事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。

Spring CloudCli

基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。

Spring CloudCommons

服务发现、负载均衡、熔断机制这种模式为Spring Cloud客户端提供了一个通用的抽象层。

Spring Cloud Config

配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储、Git以及Subversion

Spring CloudContract

Spring Cloud Netflix

针对多种Netflix组件提供的开发工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。

Spring CloudSecurity

安全工具包

Spring CloudCloudfoundry

通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台

Spring CloudConsul

封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。

Spring Cloud Sleuth

日志收集工具包,封装了Dapper,ZipkinHTrace操作.Spring Cloud应用的分布式跟踪实现

Spring Cloud Stream

数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息,实现的消息微服务。

Spring CloudZookeeper

基于ZooKeeper的服务发现与配置管理组件

Spring Boot

Spring CloudTask

用于快速构建数据处理的应用

Spring CloudGateway

Spring Cloud网关相关的整合实现

1.3             Spring Cloud的版本介绍

当我们通过搜索引擎查找一些Spring Cloud的文章或者示例的时候,往往可以在依赖中看到很多不同版本的名字, 比如: Angel.SR6, Brixton.SR5等.那么为什么Spring Cloud没有像其他的Spring的项目使用类似1.x.x版本命名规则呢?

  由于Spring Cloud不像Spring社区其他项目那样相对独立,它是拥有诸多子项目的大型综合项目.可以说是对微服务架构解决方案的综合套件的组合,起包含的各个子项目也都是进行独立的更新和迭代,各自都维护自己的发布版本号.因此每一个Spring Cloud的版本都会包含多个不同版本的子项目,为了管理每一个版本的子项目清单,避免Spring Cloud的版本号与其子项目的版本号相混淆,没有采用版本号的方式,而是通过命名的方式.

我们也可以在spring的官网上查看到对应的最新稳定版本信息: https://projects.spring.io/spring-cloud/

并且也可以看到最新Edgware.SR4稳定版对应的子项目的各个版本号

关于Spring Cloud的历史版本信息我们可以在github上查看到: https://github.com/spring-cloud/spring-cloud-release/releases

我们本次讲解的是最新的稳定版本Edgware.SR4 , 是基于Spring Boot 1.5.14.RELEASE版本实现的.

2        Spring Boot实现微服务

在正式学习Spring Cloud之前我们先使用Spring Boot实现一个微服务。

业务非常简单:

1、  商品微服务:通过商品id查询商品的服务;

2、  订单微服务:通过订单id查询订单数据,同时需要调用商品微服务查询出订单详情数据对应的商品数据

说明:

1、  对于商品微服务而言,商品微服务是服务的提供者,订单微服务是服务的消费者;

2、  对于订单微服务而言,订单微服务是服务的提供者,人是服务的消费者。

2.1             实现商品微服务

2.1.1       pom.xml文件的配置

<projectxmlns="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.</modelVersion>
<groupId>cn.itcast.microservice</groupId>
<artifactId>itcast-micorservice-item</artifactId>
<version>0.0.-SNAPSHOT</version> <!-- 定义变量 -->
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <dependencies>
<!-- 加入web的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </project>

2.1.2       创建实体Item

package cn.itcast.microservice.pojo;
publicclass Item { private Long id; // 唯一标识
private String title; // 商品标题
private String pic; // 图片的pic地址
private String desc; // 描述信息
private Long price; // 价格 }

2.1.3       编写ItemService

package cn.itcast.microservice.service;
import java.util.HashMap;
import java.util.Map;
importorg.springframework.stereotype.Service;
import cn.itcast.microservice.pojo.Item;
@Service
publicclass ItemService { privatestaticfinal Map<Long, Item>MAP = new HashMap<Long, Item>(); static { // 准备一些静态数据
MAP.put(1L, new Item(1L, "商品标题1", "http://图片1", "商品描述1", 1000L));
MAP.put(2L, new Item(1L, "商品标题2", "http://图片2", "商品描述2", 2000L));
MAP.put(3L, new Item(1L, "商品标题3", "http://图片3", "商品描述3", 3000L));
MAP.put(4L, new Item(1L, "商品标题4", "http://图片4", "商品描述4", 4000L));
MAP.put(5L, new Item(1L, "商品标题5", "http://图片5", "商品描述5", 5000L));
MAP.put(6L, new Item(1L, "商品标题6", "http://图片6", "商品描述6", 6000L));
MAP.put(7L, new Item(1L, "商品标题7", "http://图片7", "商品描述7", 7000L));
MAP.put(8L, new Item(1L, "商品标题8", "http://图片8", "商品描述8", 8000L));
} /**
* 模拟实现商品查询
*
* @param id
* @return
*/
public Item queryItemById(Long id) {
returnMAP.get(id);
}
}

2.1.4       编写ItemController

package cn.itcast.microservice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RestController;
import cn.itcast.microservice.pojo.Item;
import cn.itcast.microservice.service.ItemService; @RestController
publicclass ItemController { @Autowired
private ItemService itemService; /**
* 对外提供接口服务,查询商品信息
*
* @param id
* @return
*/
@GetMapping(value = "/item/{id}")
public Item queryItemById(@PathVariable("id") Long id) {
returnthis.itemService.queryItemById(id);
}
}

2.1.5       程序入口

package cn.itcast.microservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication//声明这是一个Spring Boot项目
publicclassItemApplication {
publicstaticvoid main(String[] args) {
SpringApplication.run(ItemApplication.class, args);
}
}

2.1.6       创建配置文件

在src/main/resources目录下创建一个application.properties配置文件,在该文件中可以配置如下内容:

server.port=

指定服务启动占用的端口

2.1.7       启动项目进行访问

2.2             实现订单微服务

2.2.1       pom.xml文件的配置

<projectxmlns="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.</modelVersion>
<groupId>cn.itcast.microservice</groupId>
<artifactId>itcast-microservice-order</artifactId>
<version>0.0.-SNAPSHOT</version> <!-- 定义变量 -->
<properties>
<java.version>1.8</java.version>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <dependencies>
<!-- 加入web的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

2.2.2       创建实体Order

package cn.itcast.microservice.pojo;
import java.util.Date;
import java.util.List; publicclassOrder {
privateStringorderId; // 订单的id
privateLonguserId; // 用户id
privateDatecreateDate; // 创建时间
privateDateupdateDate; // 修改时间
privateList<OrderDetail>orderDetails; // 订单详情
}

2.2.3       创建实体OrderDetail

package cn.itcast.microservice.pojo;

publicclassOrderDetail {

      privateStringorderId ;                 // 订单id
privateItemitem ; // 商品 }

2.2.4       复制Item实体

2.2.5       编写OrderService

该Service实现的根据订单Id查询订单的服务,为了方便测试,我们将构造数据实现,不采用查询数据库的方式。

package cn.itcast.microservice.service;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import cn.itcast.microservice.pojo.Item;
import cn.itcast.microservice.pojo.Order;
import cn.itcast.microservice.pojo.OrderDetail; @Service
public class OrderService {
private static final Map<String, Order> MAP = new HashMap<String, Order>(); static {
// 构造测试数据
Order order = new Order();
order.setOrderId("");
order.setCreateDate(new Date());
order.setUpdateDate(order.getCreateDate());
order.setUserId(1L); // 创建OrderDetail集合对象
List<OrderDetail> orderDetails = new ArrayList<OrderDetail>();
Item item = new Item(); // 此处并没有商品的数据,需要调用商品微服务获取
item.setId(1L);
orderDetails.add(new OrderDetail(order.getOrderId(), item));
item = new Item(); // 构造第二个商品数据
item.setId(2L);
orderDetails.add(new OrderDetail(order.getOrderId(), item));
// 将OrderDetail数据集设置给Order对象
order.setOrderDetails(orderDetails);
// 将Order对象添加到Map中
MAP.put(order.getOrderId(), order);
} /**
* 根据订单id查询订单数据
*
* @param orderId
* @return
*/
public Order queryOrderById(String orderId) {
Order order = MAP.get(orderId);
// 获取Order中的OrderDetail列表数据,然后遍历集合获取每一个OrderDetail,然后调用商品微服务根据商品的id查询商品数据
return order;
}
}

2.2.6       实现ItemService

package cn.itcast.microservice.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import cn.itcast.microservice.pojo.Item;
@Service
publicclassItemService { @Autowired
privateRestTemplaterestTemplate ; /**
* 根据商品的id进行查询
* @param id
* @return
*/
publicItem queryById(Longid) {
// 使用HttpClient工具发送请求获取商品的数据
// 我们也可以使用spring给我们提供的另个一个类RestTemplate,来发送Http请求
Itemitem = restTemplate.getForObject("http://localhost:8081/item/" + id, Item.class) ;
// 返回
returnitem ;
}
}

2.2.7       完善OrderService

@Autowired
privateItemServiceitemService ; /**
* 根据订单id查询订单数据
*
* @param orderId
* @return
*/
publicOrder queryOrderById(StringorderId) { Orderorder = MAP.get(orderId);
// 获取Order中的OrderDetail列表数据,然后遍历集合获取每一个OrderDetail,然后调用商品微服务根据商品的id查询商品数据
for (OrderDetailorderDetail : order.getOrderDetails()) {
Itemitem = itemService.queryById(orderDetail.getItem().getId()) ;
orderDetail.setItem(item);
}
returnorder;
}

2.2.8       编写OrderController

package cn.itcast.microservice.controller;
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;
import cn.itcast.microservice.pojo.Order;
import cn.itcast.microservice.service.OrderService; @RestController
public class OrderController {
@Autowired
private OrderService orderService; @GetMapping(value = "/order/{orderId}")
public Order queryOrderById(@PathVariable("orderId") String orderId) {
return this.orderService.queryOrderById(orderId);
}
}

2.2.9       编写启动类

package cn.itcast.microservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
publicclassOrderApplication {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 程序入口
publicstaticvoid main(String[] args) {
/**
* 启动程序
*/
SpringApplication.run(OrderApplication.class, args) ;
}
}

2.2.10 创建配置文件

在src/main/resources目录下创建一个application.properties配置文件,在该文件中可以配置如下内容:

server.port=

2.2.11 启动测试

2.2.12 优化

我们在使用RestTemplate发送请求的时候,底层其实使用的JDK中的HttpURLConnection来进行请求的发送,其实RestTemplate底层的实现也可以使用一些第三方的工具类比如: HttpClient , OkHttp

  使用HttpClient

<!-- 添加HttpClient工具 -->
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
</dependency>
@Bean
publicRestTemplate restTemplate() {
returnnew RestTemplate(new HttpComponentsClientHttpRequestFactory());
}

怎么证明底层使用的就是HttpClient呢? 我们可以将HttpClient的依赖包删除掉,项目在启动的时候就报错,那么就说明底层使用的就是HttpClient

  使用OkHttp

okhttp是一个封装URL,比HttpClient更友好易用的工具。目前似乎okhttp更流行一些。

<!-- 添加OkHttp依赖 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.</version>
</dependency>
@Bean
publicRestTemplate restTemplate() {
returnnew RestTemplate(new OkHttp3ClientHttpRequestFactory()); }

2.3             发现问题与解决问题

2.3.1       问题描述

在刚才的服务调用过程中我们的商品服务地址是直接写死在程序中,存在硬编码问题

如果商品微服务部署了多个,那么我们订单微服务如何去调用呢?

2.3.2       问题处理

1. 关于硬编码的问题我们可以使用配置文件处理,我们可以将地址信息编写到配置文件中,然后读取配置文件获取请求地址信息.

在配置文件中加入如下配置:

itcast.item.url=http://127.0.0.1:8081/item/

修改ItemService的实现,通过@Value注解获取该值

package cn.itcast.microservice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import cn.itcast.microservice.pojo.Item; @Service
public class ItemService { @Autowired
private RestTemplate restTemplate ; @Value("${itcast.item.url}")
private String itemUrl ; /**
* 根据商品的id进行查询
* @param id
* @return
*/
public Item queryById(Long id) {
// 我们也可以使用spring boot给我们提供的另个一个类RestTemplate,来发送Http请求
Item item = restTemplate.getForObject(itemUrl + id, Item.class) ;
// 返回
return item ;
}
}

注: 我们本次的解决方案只是一种临时的处理方案,如果我们商品微服务的ip地址发送了改变,那么我们对应的订单微服务的配置文件也需要做响应的改变.因此这种处理方案并没有本质的解决硬编码的问题.

2. 如果商品微服务部署了多个,那么我们订单微服务如何去调用呢?

关于这个问题,有的开发人员可能会想. 我们可以将多个商品微服务的地址配置到配置文件中,然后在进行读取配置文件的地址,进行调用.听起来好像可以,但是我们需要考虑以后问题就是后期维护的问题.

如果商品微服务的我们又添加或者减少了一个部署,相应的我们需要去更改配置文件的内容

如果商品微服务的ip地址发送了改变,那么我们也需要相应的修改配置文件的地址

所以我们自己这样实现比较麻烦,我们可以使用服务注册于发现机制来完成。

3        Spring Cloud快速入门

服务注册于发现机制架构图如下:

由上图可以看出:

1、  服务提供者将服务注册到注册中心

2、  服务消费者通过注册中心查找服务

3、  查找到服务后进行调用(这里就是无需硬编码url的解决方案)

3.1             注册中心Eureka

Spring Cloud提供了多种注册中心的支持,如:Eureka、ZooKeeper等。推荐使用Eureka。

Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix Eureka做了二次封装。主要负责完成微服务架构中的服务治理功能。

原理如下图所示:

Eureka包含两个组件:Eureka ServerEureka Client

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client是一个java客户端,用于简化与Eureka Server的交互

在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

3.2             编写Eureka Server

3.2.1       pom.xml

<projectxmlns="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.</modelVersion>
<groupId>cn.itcast.microservice</groupId>
<artifactId>itcast-microservice-eureka</artifactId>
<version>0.0.-SNAPSHOT</version> <!-- 定义变量 -->
<properties>
<java.version>1.8</java.version>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <!-- 导入Spring Cloud的依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 导入Eureka服务的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
</project>

3.2.2       启动类

package cn.itcat.microservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer //申明这是一个Eureka服务端
@SpringBootApplication
publicclassEurekaServer {
publicstaticvoid main(String[] args) {
SpringApplication.run(EurekaServer.class, args) ;
}
}

3.2.3       配置文件

#服务端口号
server.port= # 是否需要将自己注册到注册中心中,因为本身就是一个注册中心,所以不需要将自己注册到注册中心中
eureka.client.registerWithEureka=false # 是否从注册中心中获取注册信息
eureka.client.fetchRegistry=false # 客户端和服务端进行交互的地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:${server.port}/eureka/

3.2.4       启动程序访问服务端

访问地址: http://localhost:6868/

3.3             商品微服务注册到注册中心

接下来,我们需要将商品的微服务注册到Eureka服务中。

3.3.1       修改pom文件

引入Spring Cloud的管理依赖以及Eureka服务依赖。

<projectxmlns="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.</modelVersion>
<groupId>cn.itcast.microservice</groupId>
<artifactId>itcast-micorservice-item</artifactId>
<version>0.0.-SNAPSHOT</version> <!-- 定义变量 -->
<properties>
<java.version>1.8</java.version>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <!-- 导入Spring Cloud的依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<!-- 加入web的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 导入Eureka服务的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
</project>

3.3.2       修改配置文件

#应用端口号
server.port= #应用名称
spring.application.name=itcast-microservice-item # 是否需要将自己注册到注册中心中,默认值true
eureka.client.registerWithEureka=true # 是否从注册中心中获取注册信息,默认值true
eureka.client.fetchRegistry=false # 客户端和服务端进行交互的地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:6868/eureka/ #将自己的ip地址注册到Eureka服务中
eureka.instance.prefer-ip-address=true           

3.3.3       修改启动类

package cn.itcast.microservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient// 声明这是Eureka的客户端
@SpringBootApplication// 声明这是一个Spring Boot项目
public class ItemApplication { public static void main(String[] args) {
SpringApplication.run(ItemApplication.class, args);
} }

3.3.4       启动商品微服务

至此我们就已经将商品微服务注册到Eureka注册中心了.

3.4             订单系统从Eureka中发现服务

3.4.1       修改pom.xml

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

引入Spring Cloud的管理依赖以及Eureka服务依赖。

<projectxmlns="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.</modelVersion>
<groupId>cn.itcast.microservice</groupId>
<artifactId>itcast-microservice-order</artifactId>
<version>0.0.-SNAPSHOT</version> <!-- 定义变量 -->
<properties>
<java.version>1.8</java.version>
</properties> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5..RELEASE</version>
</parent> <!-- 导入Spring Cloud的依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<!-- 加入web的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- 添加OkHttp依赖 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency> <!-- 导入Eureka服务的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
</project>

3.4.2       修改配置文件

#应用端口号
server.port=
itcast.item.url=http://127.0.0.1:8081/item/ #应用名称
spring.application.name=itcast-microservice-order # 是否需要将自己注册到注册中心中,默认值true
eureka.client.registerWithEureka=false # 是否从注册中心中获取注册信息, 默认值true
eureka.client.fetchRegistry=true # 客户端和服务端进行交互的地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:6868/eureka/

3.4.3       修改ItemService

package cn.itcast.microservice.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import cn.itcast.microservice.pojo.Item; @Service
public class ItemService { @Autowired
private RestTemplate restTemplate ; @Autowired
private DiscoveryClient discoveryClient ; /**
* 根据商品的id进行查询
* @param id
* @return
*/
public Item queryById(Long id) { // 获取商品微服务服务列表
String itemServiceId = "itcast-microservice-item" ;
List<ServiceInstance> instances = discoveryClient.getInstances(itemServiceId) ;
if(instances.isEmpty()) {
return null ;
} // 获取实例对象
ServiceInstance instance = instances.get() ;
String url = "http://" + instance.getHost() + ":" + instance.getPort() ; // 发送请求
Item item = restTemplate.getForObject(url + "/item/" + id, Item.class) ; // 返回
return item ;
}
}

3.4.4       修改启动

package cn.itcast.microservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; @EnableDiscoveryClient// 声明这是一个Eureka的客户端
@SpringBootApplication
public class OrderApplication { // 程序入口
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args) ;
}
}

3.4.5       启动测试

响应的数据如下:

可以看到以及获取到数据,但是,我们发现响应的数据变成了xml结构。

3.4.6       解决响应变成xml的问题

由于我们引入了eureka server的依赖,导致破坏了之前SpringMVC默认的配置,从而导致了响应成了xml。

解决方法:排除eureka server中的xml依赖,如下:

<!-- 导入Eureka服务的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</exclusion>
</exclusions>
</dependency>

测试

 注意:在Eureka的服务端不能排除XML依赖,否则启动不了Eureka Server

Spring Cloud(一)简单的微服务集成Eureka的更多相关文章

  1. 【译文】用Spring Cloud和Docker搭建微服务平台

    by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...

  2. 手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)

    背景 公司去年开始使用dotnet core开发项目.公司的总体架构采用的是微服务,那时候由于对微服务的理解并不是太深,加上各种组件的不成熟,只是把项目的各个功能通过业务层面拆分,然后通过nginx代 ...

  3. spring cloud+.net core搭建微服务架构:服务注册(一)

    背景 公司去年开始使用dotnet core开发项目.公司的总体架构采用的是微服务,那时候由于对微服务的理解并不是太深,加上各种组件的不成熟,只是把项目的各个功能通过业务层面拆分,然后通过nginx代 ...

  4. 使用 Spring Cloud 和 Docker 构建微服务架构

    如何使用Spring Boot.Spring Cloud.Docker和Netflix的一些开源工具来构建一个微服务架构. 本文通过使用Spring Boot.Spring Cloud和Docker构 ...

  5. 从 Spring Cloud 开始,聊聊微服务架构实践之路

    [编者的话]随着公司业务量的飞速发展,平台面临的挑战已经远远大于业务,需求量不断增加,技术人员数量增加,面临的复杂度也大大增加.在这个背景下,平台的技术架构也完成了从传统的单体应用到微服务化的演进. ...

  6. Spring Cloud和Docker搭建微服务平台

    用Spring Cloud和Docker搭建微服务平台 This blog series will introduce you to some of the foundational concepts ...

  7. 【Spring Cloud学习之一】微服务架构

    一.网站架构模式发展 单体应用-->SOA-->微服务 1.分布式项目与项目集群分布式项目:根据业务需求进行拆分成N个子系统,多个子系统相互协作才能完成业务流程子系统之间通讯使用RPC远程 ...

  8. spring cloud+dotnet core搭建微服务架构:配置中心(四)

    前言 我们项目中有很多需要配置的地方,最常见的就是各种服务URL地址,这些地址针对不同的运行环境还不一样,不管和打包还是部署都麻烦,需要非常的小心.一般配置都是存储到配置文件里面,不管多小的配置变动, ...

  9. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

随机推荐

  1. spring和springmvc

    1. 为什么使用Spring ? 1). 方便解耦,简化开发 通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合. 2). AOP编程的 ...

  2. ThinkCMF_X1.6.0-X2.2.3框架任意内容包含漏洞的简单分析复现(附自动化验证脚本)

    1.漏洞概述 攻击者可利用此漏洞构造恶意的url,向服务器写入任意内容的文件,达到远程代码执行的目的 2.影响版本 ThinkCMF X1.6.0 ThinkCMF X2.1.0 ThinkCMF X ...

  3. Codeforces Round #601 (Div. 2) E2. Send Boxes to Alice (Hard Version)

    Codeforces Round #601 (Div. 2) E2. Send Boxes to Alice (Hard Version) N个盒子,每个盒子有a[i]块巧克力,每次操作可以将盒子中的 ...

  4. 配置VScode c语言环境

    vscode 提示 <sys/socket.h>找不到, 原来是不同平台上,头文件不一样. 参考:https://blog.csdn.net/qq_28581077/article/det ...

  5. el-tabs 使用

    el-tabs 使用 文章标题 网址 https://www.cnblogs.com/yuxiaole/p/9523735.html https://www.jianshu.com/p/571d832 ...

  6. C++将模板的声明和定义放置在同一个头文件里

    1. 一个类: 头文件用于保存类的声明:定义文件保存类的实现.   2. 分离编译模式: 允许在一个编译单元(.cpp文件)中定义函数.类型.类对象等,然后在另一个编译单元中引用它们.编译器处理完所有 ...

  7. codeforces1267G

    考虑我们在某个时刻,剩下的数有 $ i $ 个,这些数的和为 $ j $,那么我们期望要抽 $ n \over i $ 次才能取到一个新的物品,这个物品的期望权值为 $ j \over i $,我们花 ...

  8. day008-python内置函数

    一.ptthon内置函数 二.内置函数详细概述 2.1  abs(x):函数返回数字的绝对值. 注意: 1)x -- 数值表达式,可以是整数,浮点数,复数. 2)如果参数是一个复数,则返回它的大小. ...

  9. Eclipse中将java类打成jar包形式运行

    记录一次帮助小伙伴将java类打成jar包运行 1.创建java project项目 file > new > project > java project 随便起一个项目名称,fi ...

  10. netflix conductor 学习(一)docker-compose 运行

    为了方便学习以及使用netflix conductor 基于官方的dockerfile,构建了server 以及ui 的容器镜像并push dockerhub 环境准备 官方docker-compos ...