您的位置:首页 > 编程语言 > Java开发

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:


访问成功啦~~鼓掌!!
到这里,一个基础到不能再基础的微服务小架子就搭起来了,之后就是不断的在这里面添砖加瓦,细化服务,添加功能,集群服务器,分布式部署....当然,这些事是那些大牛们干的事情,我一个小四初级小猿就不掺和了,比我更低的猿们~加油!!


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐