SpringCloud微服务框架搭建

一、微服务架构

1.1什么是分布式
不同模块部署在不同服务器上
作用:分布式解决网站高并发带来问题
1.2什么是集群
多台服务器部署相同应用构成一个集群
作用:通过负载均衡设备共同对外提供服务
1.3什么是RPC
RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。
它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即无论是调用本地接口/服务的还是远程的接口/服务,本质上编写的调用代码基本相同。
比如两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数或者方法,由于不在一个内存空间,不能直接调用,这时候需要通过就可以应用RPC框架的实现来解决
1.3.1restful、soap、rpc
(1)RESTful是一种架构设计风格,提供了设计原则和约束条件,而不是架构。而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务。
(2)SOAP,简单对象访问协议是一种数据交换协议规范,
是一种轻量的、简单的、基于XML的协议的规范。SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的。
SOAP的消息是基于xml并封装成了符合http协议,因此,它符合任何路由器、 防火墙或代理服务器的要求。
soap可以使用任何语言来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台无需修改即可正常使用。
(3)RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
1.3.2rpc远程调用框架
几种比较典型的RPC的实现和调用框架。
(1)RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol)
和java的原生序列化。
(2)Hessian,是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。
(3)thrift是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。
(4)SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。
1.4什么是SOA
业务系统分解为多个组件,让每个组件都独立提供离散,自治,可复用的服务能力
通过服务的组合和编排来实现上层的业务流程
作用:简化维护,降低整体风险,伸缩灵活
1.5什么是微服务
架构设计概念,各服务间隔离(分布式也是隔离),自治(分布式依赖整体组合)其它特性(单一职责,边界,异步通信,独立部署)是分布式概念的跟严格执行
SOA到微服务架构的演进过程
作用:各服务可独立应用,组合服务也可系统应用(巨石应用[monolith]的简化实现策略-平台思想)
1.6使用RPC http技术实现会员与订单系统通讯

二、微服务架构

三、SpringCloud

SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。
四、服务提供者与消费关系

服务提供者:提供服务被人调用
消费者:调用被人服务

五、服务的注册与发现(Eureka )

在这里,我们需要用的的组件上Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。
4.1 服务注册
4.1.1创建eurekaserver 项目
4.1.2引入maven依赖
以上都是概念。

image.png

以上是我的springcloud项目,eureka是注册中心,zuul是注册网关,ribbon和feign都是cloud的rpc远程调用。
zuul主要是用来配置网关

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.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>
<!--eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

4.3配置application.yml

server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4.4启动EurekaServer

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

1.eureka.client.registerWithEureka=true #是否将自身注册
2.eureka.client.fetchRegistry=false #如果为true,启动时报警.
4.5打开eureka server 界面的

image.png

4.2 服务提供者
创建一个服务提供者 (eureka client),当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。

4.2.1 创建项目eurekaclient
4.2.2 引入maven依赖

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.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.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

4.2.3 application.yml配置

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name: service-hi

4.2.4 发布服务
通过注解@EnableEurekaClient 表明自己是一个eurekaclient.

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHiApplication { public static void main(String[] args) {
SpringApplication.run(ServiceHiApplication.class, args);
} @Value("${server.port}")
String port; @RequestMapping("/hi")
public String home(@RequestParam String name) {
return "hi " + name + ",i am from port:" + port;
} }

4.2.5演示效果

需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。 启动工程,打开http://localhost:8761 ,即eureka server 的网址:

image.png

你会发现一个服务已经注册在服务中了,服务名为SERVICE-HI ,端口为7862
这时打开 http://localhost:8762/hi?name=forezp ,你会在浏览器上看到 :
hi forezp,i am from port:8762

一、 服务消费者(Feign)

什么是Feign
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。
它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。
Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
简而言之:
Feign 采用的是基于接口的注解
Feign 整合了ribbon
准备工作
继续用上一节的工程, 启动eureka-server,端口为8761; 启动service-hi 两次,端口分别为8762 、8773.
准备工创建一个feign的服务
新建一个spring-boot工程,取名为serice-feign,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign、Eureka的起步依赖
spring-cloud-starter-eureka、Web的起步依赖spring-boot-starter-web,代码如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.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.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> <repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

application.yml配置
在工程的配置文件application.yml文件,指定程序名为service-feign,端口号为8765,服务注册地址为http://localhost:8761/eureka/ ,代码如下:

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8765
spring:
application:
name: service-feign

定义一个feign接口

@FeignClient(value = "service-hi")
public interface SchedualServiceHi {
@RequestMapping(value = "/hi", method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}

一个”/hi”的API接口

@RestController
public class HiController {
@Autowired
SchedualServiceHi schedualServiceHi;
@RequestMapping(value = "/hi",method = RequestMethod.GET)
public String sayHi(@RequestParam String name){
return schedualServiceHi.sayHiFromClientOne(name);
}
}

启动方式

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class SericeFeign { public static void main(String[] args) {
SpringApplication.run(SericeFeign.class, args);
} }

演示效果

启动程序,多次访问http://localhost:8765/hi?name=forezp(http://localhost:8765/hi?name=forezp),浏览器交替显示:

hi forezp,i am from port:8762

hi forezp,i am from port:8763

Hystrix断路器

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
为了解决这个问题,业界提出了断路器模型。
7.1 什么是Hystrix
Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:

image.png

较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。

image.png

断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

准备工作

这篇文章基于上一篇文章的工程,首先启动上一篇文章的工程,启动eureka-server 工程;启动service-hi工程,它的端口为8762。
在ribbon使用断路器
改造serice-ribbon 工程的代码,首先在pox.xml文件中加入spring-cloud-starter-hystrix的起步依赖:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

改造service
改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为”hi,”+name+”,sorry,error!”,代码如下:

@Service
public class HelloService { @Autowired
RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiError")
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name=" + name, String.class);
} public String hiError(String name) {
return "hi," + name + ",sorry,error!";
}
}

在启动类上加入

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix //断路器
public class App { public static void main(String[] args) {
SpringApplication.run(App.class, args);
} @Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
} }

演示效果

springcloud微服务架构搭建的更多相关文章

  1. springcloud微服务架构搭建:服务调用

    spring-cloud调用服务有两种方式,一种是Ribbon+RestTemplate, 另外一种是Feign. Ribbon是一个基于HTTP和TCP客户端的负载均衡器,类似nginx反向代理,可 ...

  2. springcloud微服务架构搭建入门笔记

    注册管理服务器 应用入口配置 @SpringBootApplication @EnableEurekaServer public class GatewayApplication { public s ...

  3. Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案

    Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...

  4. Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战

    Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...

  5. Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

    Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...

  6. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  7. SpringCloud微服务架构和SOA架构

    1,传统的三层架构 在传统的架构中,SSH,SSM,主要分为web 控制层,业务逻辑层,数据库访问层,单点项目,项目没有拆分,所有的开发任务全部写在一个项目中,耦合度比价高,如果程序中的一个功能出现了 ...

  8. SpringCloud微服务架构分布式组件如何共享session对象

    一.简单做一个背景说明1.为说明问题,本文简单微服务架构示例如下 2.组件说明分布式架构,每个组件都是集群或者主备.具体说明如下:zuul service:网关,API调用都走zuul service ...

  9. 关于SpringCloud微服务架构概念的一点理解

    目前微服务是非常火的架构或者说概念,也是在构建大型互联网项目时采用的架构方式. 1.单体架构单体架构,是指将开发好的项目打成war包,然后发布到tomcat等容器中的应用. 假设你正准备开发一款与Ub ...

随机推荐

  1. Android API之onLayout, onMeasure

    android.view.ViewGroup protected void onLayout(boolean changed, int l, int t, int r, int b) 执行layout ...

  2. Linux命令-文件处理命令:more

    分页查看文件命令,区别于翻页查看文件命令less more /etc/services 查看etc目录中的services文件 注意:空格或f是翻页,回车Enter是换行,q或Q是退出.

  3. 使用jquery的 uploadify,在谷歌浏览器上总会崩溃的解决方法

    最近做的项目使用了jquery的uploadify,但是在谷歌浏览器测试总是会出现崩溃.如: 因为是java项目. 解决的办法是: 给引入的js加上一个参数,时间戳就可以,防止缓存,使每一次都请求.( ...

  4. dll中使用exe中的变量

    注意:输出目录为:Result共享目录 1.exe项目: // EXE.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h" extern" ...

  5. QQ窗体的控制,同步异步打开360网盘,控制360网盘窗体的移动

     1.通过system启动飞秋进程的方式: 2.Windows下杀死进程的方式是:taskkill /f/im QQ.exe.截图例如以下: watermark/2/text/aHR0cDovL2 ...

  6. s:if 标签用法总结和举例

    http://www.360doc.com/content/11/1108/18/6161903_162838014.shtml

  7. jsp常用标签和标签库及javaBean规范

    1 常用标签forward,pararm,include <jsp:forward page=""></jsp:forward> <jsp:param ...

  8. Oracle 10g如何对用户姓名,按首字母排序、查询

    首先介绍Oracle 9i新增加的一个系统自带的排序函数  1.按首字母排序  在oracle9i中新增了按照拼音.部首.笔画排序功能.设置NLS_SORT值      SCHINESE_RADICA ...

  9. Android学习笔记(八)——显示运行进度对话框

    显示运行进度对话框 我们经常有这种经历:运行某一应用程序时.须要等待一会,这时会显示一个进度(Please Wait)对话框,让用户知道操作正在进行. 我们继续在上一篇中的程序中加入代码~ 1.在上一 ...

  10. Java模拟公司置办货物系统(二)

    採用MVC风格,将数据写入文件,模拟公司置办货物系统.  A类表示普通员工,B类表示部门精力,C类表示採购部,D类表示资源管理部. 订单状态 1.表示申请状态 2.表示通过审批 3.表示未通过审批 4 ...