Springcloud是一款微服务框架,它基于Springboot,可以使用它用来管理纵向拆分的项目,将一个个的小项目变成微服务。下面简单的搭建一个微服务,使用eureka组件实现注册中心,使用ribbon组件实现微服务调用,使用zuul网关实现真实服务地址和访问地址的分离,其他技术后续补充。
springcloud和nginx
前面学习过nginx,它除了可以实现动静分离,还可以实现负载均衡,即可以将项目做成分布式tomcat集群,前端访问可以随机或者按照权重值访问后端服务。但是nginx有一个小缺点,如果单台服务器出现问题、或者需要添加服务器,需要修改conf.xml配置文件,或某台服务器出现问题如何容错等,ngnix是无法实现。简单来说它缺少管理者的因子,需要人为''介入'',在这种情况下,springcloud就可以弥补nginx的不足,它不仅仅可以实现分布式,负载均衡,并且对微服务有管理、容错、监听的能力。
springcloud
springcloud是spring家族的一员,它是一个微服务框架,用在大型分布式应用的开发,官网:https://spring.io/projects/spring-cloud,除了springcloud外,其他比较出名的微服务框架还有dubbo。
如果一个项目比较小,直接使用springboot,或者ssm做成单体项目就可以,但是如果一个项目比较大,就需要考虑到拆分,比较常见的就是横向拆分和纵向拆分。
(1)纵向拆分:大项目分成很多小项目,如电商网站的登录注册系统、商品系统、秒杀系统、搜索系统、购物车系统等,都是拆分后的小项目,这就是纵向拆分。
(2)横向拆分:一个纵向拆分后的项目,也可以继续拆分,如有人专门做控制层,有人做业务层,这就是横向拆分。
springcloud是如何对拆分后的项目进行管理的呢,这就需要用到它的关键组件,这里暂时先记录eureka、ribbon和zuul三种组件,其他组件如config、feign和hystrix后续单独补充。
(1)eureka:服务治理组件,利用它的注册和发现机制,实现整体微服务的管理,提供其他服务注册,并可以发现其他服务,springcloud只提供了一种这种治理组件。
(2)ribbon:通过eureka发现机制,可以负载均衡、随机或者根据权重来调用其他提供服务的组件。
(3)zuul:网关组件,唯一对外暴露接口地址的组件,实现外界访问地址和内部请求地址的分离,对外影藏了真实的地址。
下面使用一下这几个组件。
eureka
整个springcloud的核心组件之一,它就像一个''管理者'',利用自己的注册和发现的能力,来管理着一批注册在它身上的微服务。即其他服务可以注册在eureka注册中心,它管理着一批这样的已经注册的微服务,并对外提供服务,同时注册中心会将其他服务注册的信息保存到本地,通过定时更新来维护和其他服务的关系。简单来说注册中心就像''工商局'',各种公司之类的服务提供者都在这里注册,完了就可以对外提供服务了。
a.搭建eureka注册中心
使用IDEA,搭建一个eureka注册中心,搭建是基于springboot,需要利用springboot的自动配置和'约定大于配置'的特点,来配合springcloud简化搭建过程,注意两者版本的兼容,可以参考文末博客。
(1)pom文件导入springboot父pom、以及springcloud依赖。
<?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.boe</groupId> <artifactId>Eureka-server01</artifactId> <version>1.0-SNAPSHOT</version> <name>Eureka-server01</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <!--使用springboot的资源,结构特性。另外使用springcloud的所有依赖环境--> <!-- 基于springboot,继承springboot-parent,引入springboot的父pom文件 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <!--1.5.9是稳定版本--> <version>1.5.9.RELEASE</version> </parent> <!--导入springcloud的父pom资源,声明式依赖,子工程手动导入时就导包,不导入就不导入包--> <dependencyManagement> <dependencies> <!--导入springcloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.RELEASE</version> <!--注意通过坐标找到的spring-cloud-dependencies-Edgware.RELEASE.pom文件中,打包方式为pom,因此需要这里type为pom--> <type>pom</type> <!--maven scope方式常用有很多种,默认为compile,还有test、provided、system等--> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--以上两步,完成继承父springboot pom依赖,并导入springcloud的依赖管理--> <dependencies> <!--引入eureka注册中心的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> <!--建议使用下面的artifactId--> <!--<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>--> </dependency> <!-- spring-boot-starter-web 已经在eureka-server中传递,因此这里不需要配置springboot的starter-web--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!--springboot运行jar包的插件,可以直接使用java -jar jar包名来运行springboot--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!--指定jar包运行的main class--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <!--<configuration>--> <!--<archive>--> <!--<manifest>--> <!--<addClasspath>true</addClasspath>--> <!--<mainClass>com.StarterEurekaServer</mainClass> <!– 此处为主入口–>--> <!--</manifest>--> <!--</archive>--> <!--</configuration>--> </plugin> </plugins> </build> </project>
(2)资源目录下添加application.properties文件,添加服务端口、服务名、注册eureka中心地址等信息。
# 端口
server.port=8088
# 客户端通过ip底层注册
# eureka.client.prefer-ip-address=true
eureka.client.preferIpAddress=true
#暂时先关闭,当前注册中心作为客户端
# 在注册中心本身,使得具有注册和发现的能力,如果要实现HA,需要改成true,这样就会访问注册中心的接口
eureka.client.regist-with-eureka=false
# 关闭发现抓取注册信息的能力
eureka.client.fetch-registry=false
# 注册中心的地址,http请求的接口
eureka.client.serviceUrl.defaultZone=http://localhost:8088/eureka
# 当前工程提供一个服务名称,相同功能的工程创建集群,都是一个名称,以当前服务名为key保存在当前服务的所有节点信息的map对象中
# 如果是同一个name,就可以创建HA高可用
spring.application.name=eureka-server
# 可以关闭自我保护,没有收到续约,就从注册中心剔除服务
# eureka.server.enable-self-preservation=false
(3)写一个启动类,来启动注册中心,需要使用@EnableEurekaServer注解,来表名启动的是一个注册中心服务类。
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * eureka server启动类 */ @SpringBootApplication @EnableEurekaServer public class StarterEurekaServer { public static void main(String[] args) { SpringApplication.run(StarterEurekaServer.class,args); System.out.println("I am eureka server01"); } }
(4)启动后,访问注册中心地址localhost:8088,就可以查看注册中心注册的实例,这里有一个就是eureka服务自己本身,以后如果有注册的服务,都能在这里查看。
b.搭建一个微服务并注册
Eureka注册中心搭建起来后,接下里搭建一个微服务并注册在Eureka注册中心,并使用它提供的服务。
(1)pom文件与上面类似,这次搭建的是服务提供者,因此引入eureka客户端依赖(spring-cloud-starter-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.boe</groupId> <artifactId>Client01</artifactId> <version>1.0-SNAPSHOT</version> <name>Client01</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <!--使用springboot的资源,结构特性。另外使用springcloud的所有依赖环境--> <!-- 基于springboot,继承springboot-parent,引入springboot的父pom文件 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <!--导入springcloud的父pom资源--> <dependencyManagement> <dependencies> <!--导入springcloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.RELEASE</version> <!--注意通过坐标找到的spring-cloud-dependencies-Edgware.RELEASE.pom文件中,打包方式为pom,因此需要这里type为pom--> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--以上两步,完成继承父springboot pom依赖,并导入springcloud的依赖--> <dependencies> <!--引入eureka客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- spring-boot-starter-web 已经在eureka-server中传递,因此这里不需要配置springboot的starter-web--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!--springboot运行jar包的插件--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>