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. Odoo MRP模块

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10825963.html 一:MRP MRP:产品制造管理. 产品制造业务设计到以下几个关键概念: 1)BOM ...

  2. web服务器-nginx

    一.nginx之前 同步与异步: 同步与异步的重点在消息通知的方式上,也就是调用结果的通知方式不同. 同步:当一个同步调用发出去后,调用者要一直等待调用的结果通知后,才能进行后续的操作. 异步:当一个 ...

  3. 树莓派安装realvnc_server

    先 sudo raspi-config 打开VNC. 然后去realvnc官网去下载raspberry的vncserver 已经ssh连接的前提下可以电脑下载后使用scp命令转移到树莓派上,使用以下命 ...

  4. excel打开提示 文件格式和扩展名不匹配。文件可能已损坏或不安全。除非您信任其来源,否则请勿打开。是否仍要打开它?

    有的时候打开xls文档时,会提示“文件格式和扩展名不匹配.文件可能已损坏或不安全.除非您信任其来源,否则请勿打开.是否仍要打开它?” 遇到这种情况,我们需要 打开“注册表编辑器” win键+R键,打开 ...

  5. Mysql五大约束

    Mysql五大约束 约束:对表中数据的限制.保证表中数据的准确和可靠 (1)NOT NULL:非空,用于保证该字段的值不能为空 (2)DEFAULT:默认,用于保证该字段有默认值(3)PRIMARY ...

  6. wordpress站点更换域名了如何快速设置

    有时我们的wordpress站点因为各种原因需要更换域名了,如何快速设置让网站直接用新域名而不受影响呢?比如旧域名是a.com,新域名为b.com,下面这段sql代码很有用 UPDATE wp_opt ...

  7. JavaScript项目总结一

    1.类选择其下,第一个 $('selector').first()==$('selector:first')==$('selector:eq(0)') 2.如果要选择非第一个 $('selector: ...

  8. python 查询文件存放地址

    import os, time import sys import re def search(path,name): for root, dirs, files in os.walk(path): ...

  9. Python 弹出框代码

      from ctypes import * user32 = windll.LoadLibrary('user32.dll')#调用dll文件 #a是得到弹出框的选择按钮的值 user32.Mess ...

  10. “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 分组加密器(encryption)

    分组加密器(encryption) 题解点这里 #include<map> #include<stack> #include<vector> #include< ...