一、基础复习
1、什么是SpringCloud?
答:SpringCloud是一套完美的微服务解决框架。主要做RPC远程调用框架
SpringClould:注册中心Euraka(管理服务地址信息)、Ribbon做负载均衡、
rest作用调用接口。
fegin:客户端调用,接口调用方式
zuul接口网关:跨域、路由、拦截参数
hystrix:断路器 -- 服务雪崩效应、服务降级、熔断机制、限流
分布式配置中心:
springcloud bus :相当于MQ
任何的RPC远程调用框架,都有注册中心。没有注册中心,
管理服务机会会很麻烦。
二、SpringCloud服务负载均衡实现原理
1、怎么实现负载均衡 ? 就是相当于反向代理工具
答:nginx、lvs HAproxy、F5。
SpringCloud中的负载均衡ribbion:默认轮询机制
SpringCloud集成Ribbon做负载均衡
三、使用Ribbon搭建服务负载均衡
一个注册中心,两个服务,这里使用member来做集群。会员服务做集群
注册中心显示如下:
只要你这个会员服务做了集群,就会在注册中心有两个服务相同,
对应的服务IP和端口号不同的
使用ribbon来做负载均衡:首先要在pom。xml引入ribbon
在订单服务中要加上@LoadBalanced 这个注解,表示支持负载均衡
这里调用接口使用的是rest方式来调用的。
测试ribbon来做负载均衡 默认是轮询机制 可以配置其他的负载均衡算法。
四、接口网关介绍:Zuul
什么是接口网关?
答:接口网关的作用就是拦截请求,类似nginx。
接口网关的作用:拦截所有请求,任何请求先交给接口网关,
然后再用网关进行转发。这个功能类似nginx的反向代理功能。
使用项目名称进行区分,接口网关转发到实际地址。
在大公司,任何接口都不可能是直接调用的。所以要网关来控制。
五、使用Zuul搭建服务接口网关
接口网关的好处:解决跨域问题。
搭建zuul接口网关
pom.xml
<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.leeue</groupId>
<artifactId>40_service_zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<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-zuul</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>
</project>
application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8769
spring:
application:
name: service-zuul
zuul:
routes:
api-a:
# path是可以自己定义的 随便写
path: /api-member/**
service-id: service-member
api-b:
path: /api-order/**
service-id: service-order
启动:ZuulApp.java
package com.leeue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* 启动Zuul接口网关
*
* @classDesc: 功能描述:()
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年11月6日 下午1:29:51
*/
@EnableZuulProxy //注意 这个一定要加上,说明启动了Zuul接口网关拦截
@EnableEurekaClient
@SpringBootApplication
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class, args);
}
}
第六、使用Zuul网关拦截参数
拦截要继承 ZuulFilter
这里实现的是http://localhost:8769/api-order/getOrderServiceApi?token=11
请求连接必须带上token参数才能正确的去访问这个地址。
package com.leeue;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
/**
* 使用Zuul拦截参数,类似拦截器的功能
* @classDesc: 功能描述:()
* @author:<a href="leeue@foxmail.com">李月</a>
* @Version:v1.0
* @createTime:2018年11月6日 下午1:45:45
*/
@Component
public class MyFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(MyFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
public boolean shouldFilter() {
return true;
}
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("token");
if (accessToken != null) {
return null;
}
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
} catch (Exception e) {
}
return null;
}
}
传统方式:每个服务期都要写拦截器判断。
互联网:搭建一套网关系统。
在微服务里面一定要回答到网关,
面试题:A B服务 怎么保证B服务只能允许A服务进行访问?
答:使用nginx或者Zuul搭建接口网关系统进行判断请求来源。
七、分布式配置中心介绍(管理配置文件的)
1、什么是分布式配置文件中心?
答:在开发中,怎么区分环境
dev 测试环境
pre预发布
ped正式生产环境
调用接口:alibaba.api 使用httpclient 进行调用,
配置信息存放在配置中,需要发布版本。
传统项目中:
缺点:java代码读取配置,存放在永久去中,static修饰。
如果想发版,又要修改配置文件信息该怎么做?
第一种解决方案:
1、将值存放在缓存中,数据库中备份
2、后台搭建一套可视化管理配置文件项目
3、读取流程先从缓存中读取,缓存中没有再去读取数据库中
4、缓存中与数据库值不同步怎么解决?清缓存,然后再去读数据库中放入缓存中。
第二种解决方案:
将配置文件信息存放在版本控制(git/svn)种,
springCloud配置中心就是这种机制。
八、搭建分布式文件配置中心
配置中心搭建:
pom.xml文件
<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.leeue</groupId>
<artifactId>40_config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<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-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR6</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>
</project>
application.properties文件
spring.application.name=config-server
server.port=8889
#这个是你配置文件放的git上的地址
spring.cloud.config.server.git.uri=https://gitee.com/leeue14/config-leeue.git
spring.cloud.config.server.git.searchPaths=respo
spring.cloud.config.label=master
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
启动ConfigServerApplication.java
package com.leeue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer //开启配置文件中心的注解
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
这些配置后,查询配置中心有没有配置好方式访问
http://localhost:8889/foo/dev
分布式配置(文件)中心 客户端实现
pom.xml
<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.leeue</groupId>
<artifactId>40_config-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<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-config</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>
</project>
bootstrap.properties 这个文件名是固定的
文件 这里写你获取到那个配置服务端,你要读取那个配置
默认读application 或 bootstrap 这种文件名
spring.application.name=config-client
spring.cloud.config.label=master
spring.cloud.config.profile=dev
spring.cloud.config.uri= http://localhost:8889/
server.port=8881
调用
package com.leeue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
}
@Value("${userName}")
String userName;
@Value("${configName}")
String configName;
@RequestMapping(value = "/getUserName")
public String getUserName() {
return userName;
}
@RequestMapping(value = "/getConfigName")
public String getConfigName() {
return configName;
}
}
分布式配置中心作用就是:项目不需要重新打包,
只需要重启客户端就可以更新里面的内容了。
分布式配置中心,上面的例子不需要注册到Eureka里面 。
单独存在的分布式配置中心。
配置文件读取:
config-server项目 主要是读取在git/svn上面的配置文件信息
config-client项目用的配置文件信息是从config-server项目上读取的。
图解: