springboot+springcloud基础微服务架构
2018-03-14 17:43
696 查看
一,前言
这是一篇来自于一个小白到不能再小白的初初初初级级java程序员的博客,也是我的第一篇博客,所以呢,肯定是很浅显啦,我是四初级,那么这篇文章适合人群:五初级以下程序员以及未成年小孩,并且我估计也学不到什么知识....(说这些废话!有没有人看心里没点逼数么??).二,微服务简介
这里不说那些高大上的名词啦,引用一张图,容我百度一下.....嗯,找到了,就这张:很多跟我一样的萌新可能已经在默默的诅咒我了(什么鬼啊~!!博主你出来,保证不打死你!!)..咳咳...开个玩笑~这张图可不得了啊,古人云,大道至简.道理都蕴藏在这张图中啦,待我慢慢道来...在很久很久以前...呸~~串戏了,好了好了,严肃点,其实微服务,就是讲客户需求的各种各样的业务拆分成一个一个的小任务,每一个小任务都有自己的一套完整的体系,而单体应用呢就是把所有的需求,聚合成一个大的任务,独立拥有一整套体系.这么说吧,以前咱们做项目,分工是按照职能来分的,"狗蛋你做后台,丑妹你做前端,傻牛你做接口....",有了微服务就变成了"狗蛋你做用户服务,丑妹你做管理服务,傻牛你做订单服务...",丑妹:"本仙女只会html,滚!!~~"
三,做一个初步的微服务架构
做微服务也跟做单体一样,条条大路通公厕,基础框架可以用dubbo,也可以用春云(springcloud),在这里,我选择~~~~春云!!恭喜你加入我的战队,我的战队叫做,"地表最春战队"!鼓掌!!开发工具呢,这里选用idea,萌新们可能更爱eclipse,没关系,一样,有代码啥工具不行?我们不生产代码,我们只是代码的搬运工!鼓掌~~那么接下来有个小小的问题了,虽然我很爱萌新,很照顾萌新,但是春云却独爱springboot,挥泪~~那么,在搭建之前,萌新们需要先小小的学习一下春boot咯,来,送你们飞机票,去吧~~飞吧~~去拥抱HelloWorld吧!点这里~~~
为了照顾使用eclipse的同学们,这里咱们就新建一个maven项目:
然后一直next就行啦,建完后目录结构是这样子的:
接下来,添加第一个模块,eureka注册中心,这玩意的作用,就像货架一样,咱们那些微服务都得放到这上面注册了,才能让客户消费:
项目上右键,new一个module,eclipse的同学可以新建一个项目,在idea里,每一个module就相当于eclipse的一个项目,
建完后的项目结构是这样子的:
在eureka的pom.xml文件中导入相关依赖:<?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>
<artifactId>EurekaServer</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath />
</parent>
<prop
4000
erties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</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>
</project>新建一个package来存放启动类EurekaApplication.class,这里一定要新建一个包,不能直接在src/java下建启动类,否则,无法被扫描到,启动会失败的哦:@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaApplication.class).web(true).run(args);
}
}接着,在resoures目录下新建配置文件application.yml,eclipse的朋友们需要自己建src/main/resoures目录哦,配置内容如下:server.port: 1111 //这里是注册中心的端口号,可以自己改自己喜欢的
eureka.client.register-with-eureka: false
eureka.client.fetch-registry: false
eureka.client.serviceUrl.defaultZone: http://localhost:1111/eureka/然后就可以启动啦~运行启动类,访问http://localhost:1111即可,成功访问会出现这个页面:
这里就是咱们的注册中心啦,现在还是空空如也,没有任何服务,所以现在咱们要注册上几个服务,在这里,添加三个模块,分别叫做orderService1,orderService2,shareService,其中,orderservice1和2是同一种服务,share是另一种服务,这里是为后面讲负载均衡做个准备,三个服务的pom文件都是一样的:
<?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> <artifactId>shareService</artifactId> <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> </project>他们的启动类除了名字不一样,哪哪都一样:@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(OrderServiceApplication.class).web(true).run(args);
}
}application.yml配置文件也是,分别如下:
spring.application.name: service-order server.port: 2222 eureka.client.serviceUrl.defaultZone: http://localhost:1111/eureka/
spring.application.name: service-order server.port: 2223 eureka.client.serviceUrl.defaultZone: http://localhost:1111/eureka/
spring.application.name: service-share server.port: 3333 eureka.client.serviceUrl.defaultZone: http://localhost:1111/eureka/[/code]注意哦,擦亮你的双眼哦,这里两个orderService的名字是一样的,但是端口号是不一样的,这样做的目的是建两个同名的服务,为之后的负载均衡做准备,配置完毕,将所有的服务都启动吧!运行他们的启动类!然后刷新刚才的注册中心页面,看!我发现了什么?三个野生的服务!
由于同名,所有其实是两个服务,order服务有两个端口;
接下来,按照刚才的顺序,在三个服务放置启动类的包下再新建一个controller包,来作为待会咱们调用各服务的表现形式,分别如下:@RestController public class OrderController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/order" ) public String order() { ServiceInstance instance = client.getLocalServiceInstance(); logger.info("被调用了"); return "这是订单服务"; } }
@RestController public class ShareController { @Autowired private DiscoveryClient client; @RequestMapping(value = "/share") public String share() { ServiceInstance instance = client.getLocalServiceInstance(); return "这是分享服务"; } }
@RestController public class OrderController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/order" ) public String order() { ServiceInstance instance = client.getLocalServiceInstance(); logger.info("被调用了"); return "这是订单服务"; } }不要想太多,博主并没有弄错,这俩订单服务的内容和路径都是一毛一样的哦;
接下来重启所有服务,哈哈,这里肯定有人骂博主了(如果有人看的话╮(╯▽╰)╭),为什么不把controller写好再一并启动呢?多此一举,其实....我就是想看你们看不惯我又弄不死我的样子,哈~咳咳...启动完成后,分别访问: http://localhost:2222/order http://localhost:2223/order http://localhost:3333/share
就可以看到,三个服务都被成功调用啦~
就像这样.到这里,咱们成功完成了基础的微服务注册与发现,鼓掌!!接下来,就是咱们一直心心念念的负载均衡了,咱们采用比较简单的ribbon来实现,照旧添加新模块ribbon,引入依赖:<?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>
<artifactId>ribbon</artifactId>
<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.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</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>
创建启动类:@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}这里的启动类与之前的不一样,因为要通过@LoadBalanced注解来开启负载均衡,接下来创建controller类:@RestController
public class OrderController {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/order", method = RequestMethod.GET)
public String order() {
return restTemplate.getForEntity("http://SERVICE-ORDER/order?", String.class).getBody();
}
}这里要注意,http后面跟eureka中心注册时显示的服务名,
最后,配置application.yml:spring.application.name: ribbon-order
server.port: 4444
eureka.client.serviceUrl.defaultZone: http://localhost:1111/eureka/打开所有服务,包括ribbon,然后通过ribbon端口调用service-order服务: http://localhost:4444/order,多刷新调用几次,再来看控制台,你会发现:
两个不同端口的order服务在被平均调用,雨露均沾啊,这就是负载均衡的作用啦!
最后,还有一样最重要的东西,那就是api gateway,微服务网关,zuul!,zuul的作用,就是给所有的服务统一一下口令:"云起龙沙暗!请接~~接不上?你不是我们帮派的人,砍死!!"....戏精!!傻逼博主!!...好,添加zuul模块,引入依赖:<?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>
<artifactId>zuul</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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>
91b4
;spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</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>
</project>编写启动类ZuulApplication.class:@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ZuulApplication.class, args);
}
}在启动类上加入@EnableZuulProxy注解,启动zuul功能,然后新建一个filter包,创建ZuulFilterTest类,来实现校验口令的功能:public class ZuulFilterTest extends ZuulFilter{
private static Logger log = LoggerFactory.getLogger(ZuulFilterTest.class);
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String code = request.getParameter("code");
if (code==null) {
log.warn("code is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
return null;
}
log.info("code is ok");
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public String filterType() {
return "pre";
}
}之所以不叫ZuulFilter,是因为这个类继承的就是ZuulFilter...好吧,感觉有说的是废话,这个filter的功能就是校验访问者有没有携带code参数,如果没有就会返回error,拒绝访问,最后一步,配置application.yml:server:
port: 5555
spring:
application:
name: gateway-zuul
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/
zuul:
routes:
orders:
path: /service-order/**
serviceId: service-order
shares:
path: /service-share/**
serviceId: service-share
这里面要配置需要过滤的请求路径以及映射到哪个服务,接下来,启动zuul,通过zuul端口访问: http://localhost:5555/service-order/order,会发现:
然后再加入口令code访问: http://localhost:5555/service-order/order?code=t:
访问成功啦~~鼓掌!!
到这里,一个基础到不能再基础的微服务小架子就搭起来了,之后就是不断的在这里面添砖加瓦,细化服务,添加功能,集群服务器,分布式部署....当然,这些事是那些大牛们干的事情,我一个小四初级小猿就不掺和了,比我更低的猿们~加油!!
相关文章推荐
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- Spring Cloud Spring Boot mybatis分布式微服务云架构(一)快速入门
- Spring Boot和Spring Cloud微服务架构学习(五)-Docker总结
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- 企业分布式微服务云架构技术分享 Spring Cloud + Spring Boot + Mybat
- Spring Cloud Spring Boot mybatis分布式微服务云架构
- Spring Cloud Spring Boot mybatis分布式微服务云架构(十)
- Spring Cloud Spring Boot mybatis分布式微服务云架构(三十二)事务管理(2)
- Spring Cloud Spring Boot mybatis分布式微服务云架构(四十)使用AOP统一处理Web请求日志(1)
- Spring Cloud Spring Boot mybatis分布式微服务云架构(三)属性配置文件详解(1)
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- Spring Cloud Spring Boot mybatis分布式微服务云架构(六)RESTful API单元测试
- Spring Cloud Spring Boot mybatis分布式微服务云架构(十一)Web应用的统一异常处理
- spring cloud + spring boot + springmvc+mybatis分布式微服务云架构
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- Spring Cloud Spring Boot mybatis分布式微服务云架构(二)
- Spring Cloud Spring Boot mybatis分布式微服务云架构(十二)
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
- Spring Cloud Spring Boot mybatis分布式微服务云架构(二)使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程