2019独角兽企业重金招聘Python工程师标准>>>

概述

在上一篇中提到了spring cloud 面向接口调用的开发风格,这一篇会举一个简单的但完整的例子来说明整个代码结构。
代码已上传到 https://github.com/maruixiang/spring-cloud-demo/tree/master/demo1

代码结构

整个代码在demo1目录下面,包含了一个根级的parent pom文件和三个maven应用。

  • 根pom文件:所有应用的parent pom文件。
  • eureka :注册中心,用于服务注册和发现。
  • demo :demo微服务,它本身包含了两个模块,demo-api提供给第三方使用的接口;demo-service是服务的具体实现。
    为什么每个微服务多加了一层目录结构呢?因为从微服务职责划分来说,不同团队负责不同的微服务开发,每个微服务独立成项目,代码可以随时分离,不混合在一起。
  • client : 客户端调用服务。
    每个应用maven代码结构可以通过http://start.spring.io/ 、IDE工具或手动生成,这里不多述。

统一的根级的pom.xml

  • 这个文件是手工创建的,把spring boot基本信息都统一移到这里面来定义。
    spring-boot 1.5.7.RELEASE
    spring-cloud Dalston.SR3 。
  • 为了方便测试,我把三个应用的modules定义也放入了这里。而实际项目开发中,这个文件是不应该包含modules(实际开发中,这是一个基本不会修改的公共pom文件,不可能新加的微服务都放来来。正确做法是去掉modules,加入发布节点distributionManagement信息,把这个pom 通过mvn deploy 到maven 服务器上供所有的微服务使用即可)。
<?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.cehome.cloud</groupId><artifactId>cehome-cloud-parent</artifactId><version>1.0.0-SNAPSHOT</version><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.7.RELEASE</version></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><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>1.5.7.RELEASE</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Dalston.SR3</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><modules><module>eureka</module><module>demo</module><module>client</module></modules>
</project>

eureka注册中心

读音[ ju:`rika:]

定义pom

继承spring-cloud-parent ,引入依赖 spring-cloud-starter-eureka-server即可

<?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><parent><groupId>com.cehome.cloud</groupId><artifactId>spring-cloud-parent</artifactId><version>1.0.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><groupId>com.cehome.cloud</groupId><artifactId>eureka</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><name>eureka</name><description>Demo project for Spring Boot</description><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka-server</artifactId></dependency></dependencies></project>

添加spring配置

tomcat端口使用eureka约定的8761

server.port=8761
spring.application.name=eureka
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
#是不是client?肯定不是啦。为true时,可以启动,但报异常:Cannot execute request on any known server
eureka.client.fetch-registry=false
#单注册中心设为false,集群是需要设为true以便多eureka互相同步
eureka.client.eureka-with-eureka=false

启动类

package com.cehome.cloud.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}
}

启动

运行main 方法,然后访问 http://localhost:8761/

开发demo微服务

demo 本身是包含两个模块的maven应用,一个是api供第三方调用,一个是具体逻辑。

接口模块 demo-api

  • 因为需要用到Feign,所以引入Feign依赖即可。
    在pom文件中,还要引入spring-boot-thin-layout 一个很重要的maven插件。因为spring boot 缺省是编译成fat jar(60m左右),而api是要打成jar包给第三方使用的,如果打成一个spring boot结构的fat jar,第三方肯定无法使用了,所以引入了这个maven插件,会把api打成一个我们普通使用的jar包(可能就10多K),这样才能真正实现接口跟逻辑分离的效果。
<?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.cehome.cloud</groupId><artifactId>demo-api</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><parent><groupId>com.cehome.cloud</groupId><artifactId>demo-parent</artifactId><version>1.0.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><dependencies><dependency><groupId>org.springframework.boot.experimental</groupId><artifactId>spring-boot-thin-layout</artifactId><version>1.0.5.RELEASE</version></dependency></dependencies></plugin></plugins></build></project>
  • 定义接口类。接口就只有一个get()方法,访问后返回一个固定字符串。
package com.cehome.cloud.demo.api;import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;@FeignClient(name= "demo-service" )
public interface Demo1Service {@RequestMapping("/demo1/get")String get();}
  • 需要继续添加一个包含main()方法的类,这个可以随意定义。编译时spring boot 会取找一个main()方法,没有的话编译会报错。
package com.cehome.cloud.demo.api;public class DemoAPI {public static void main(String[] args) {}
}

服务模块demo-service

  • 定义pom.xml。除了spring-cloud-starter-eureka、spring-boot-starter-web、spring-cloud-starter-feign 这几个基本的微服务依赖,还要依赖上面定义的接口demo-api。
<?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.cehome.cloud</groupId><artifactId>demo-service</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><name>demo-service</name><description>Demo project for Spring Boot</description><parent><groupId>com.cehome.cloud</groupId><artifactId>demo-parent</artifactId><version>1.0.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><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-feign</artifactId></dependency><dependency><groupId>com.cehome.cloud</groupId><artifactId>demo-api</artifactId><version>1.0.0-SNAPSHOT</version></dependency></dependencies></project>
  • 定义配置文件application.properties。 spring.application.name就是service Id,跟上面@Feign注解中的名字一样。
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
server.port = 8762
spring.application.name = demo-service
  • 实现main方法。
    @EnableEurekaClient 让服务跟eureka注册中心关联,可以作为服务提供者也可以作为消费者。
package com.cehome.cloud.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
//-- provider and consumer  service
@EnableEurekaClient
@ComponentScan("com.cehome.cloud.demo")
public class DemoServiceApplication {public static void main(String[] args) {SpringApplication.run(DemoServiceApplication.class);}
}
  • 继承Demo1Service 接口,实现服务Demo1ServiceImpl。注意这里的服务实际上是一个Controller,我们为了规范和便于管理,让其继承api中定义的接口Demo1Service ;且Demo1ServiceImpl的包名也是用service,不用controller,这就是一种约定,强调这是一个服务。
package com.cehome.cloud.demo.service;import com.cehome.cloud.demo.api.Demo1Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Demo1ServiceImpl implements Demo1Service {@Overridepublic String get() {return "This is Demo1 Service";}
}
  • 验证。访问 http://localhost:8762/demo1/get

客户端调用

  • 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"><parent><groupId>com.cehome.cloud</groupId><artifactId>spring-cloud-parent</artifactId><version>1.0.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.cehome.cloud</groupId><artifactId>client</artifactId><packaging>jar</packaging><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-feign</artifactId></dependency><dependency><groupId>com.cehome.cloud</groupId><artifactId>demo-api</artifactId><version>1.0.0-SNAPSHOT</version></dependency></dependencies>
</project>
  • application.properties
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
server.port = 8763
spring.application.name = client-demo
  • spring boot主程序。
    @EnableDiscoveryClient - 仅作为消费者(客户端),如果既作为消费端又同时作为服务提供者,则用@EnableEurekaClient。

@EnableFeignClients - 指定了Feign扫描api接口的范围。Feign扫描到包含@Feign注解的interface,然后会实例化一个spring代理bean,代理各种方法调用并转成URL发送请求。

package com.cehome.cloud.client;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RestController;@SpringBootApplication
//-- consumer  http://blog.didispace.com/spring-cloud-tips-feign-rpc/
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.cehome.cloud"})
@RestController
@ComponentScan("com.cehome.cloud.client")
public class ClientApplication {public static void main(String[] args) {SpringApplication springApplication=new SpringApplication(ClientApplication.class);ConfigurableApplicationContext applicationContext=springApplication.run(args);}
}
  • 调用服务。可以看到,在pom.xml 引入demo-api后,通过
  • “@Autowired private Demo1Service demo1Service;” 方式,就像调用本地bean一样调用微服务。用户只要引入api jar包就行,不用关心服务部署在哪台机器,也不用care怎样拼接URL去调用服务,这是不是很符合java面向对象开发的要求?
  • 阅读原文

    http://click.aliyun.com/m/38898/

转载于:https://my.oschina.net/u/3637633/blog/1602982

微服务实战之春云与刀客(三)—— 面向接口调用代码结构实例相关推荐

  1. 微服务实战之春云与刀客(一)—— 微服务开篇

    春云即spring cloud ,刀客即docker,这种翻译似乎比较好玩! 这里是春云与刀客不得不说的故事,不会讲太多的入门,更多的是实战和一些规范,以及通过春云和刀客如何简化微服务开发,这些在一些 ...

  2. 微服务实战之春云与刀客(四)—— docker swarm 集群实战

    概述 docker swarm 是一个非常简单的docker 原生集群部署环境.在docker swarm 出来之前,要搭建一个docker 集群需要复杂的网络运维和配置能力,而docker swar ...

  3. 微服务实战之春云与刀客(五)—— spring cloud与docker swarm集群

    概述 原文:https://yq.aliyun.com/articles/618620 微服务与docker结合是必然的趋势,本文介绍spring cloud与docker swarm集群实现微服务极 ...

  4. SpringCloud Alibaba微服务实战(七) - 路由网关(Gateway)全局过滤

    说在前面 全局过滤器作用于所有的路由,不需要单独配置,我们可以用它来实现很多统一化处理的业务需求,比如权限认证,IP 访问限制,监控,限流等等. 创建路由网关(Gateway)启动服务cloud-ac ...

  5. SpringCloud Alibaba微服务实战(五) - Sentinel实现限流熔断

    什么是Sentinel? 请查看文章:SpringCloud Alibaba微服务实战(一) - 基础环境搭建 构建服务消费者cloud-sentinel进行服务调用 服务创建请查看文章:Spring ...

  6. SpringCloud Alibaba微服务实战(四) - Nacos Config 配置中心

    说在前面 Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台.Nacos Config就是一个类似于SpringCloud Config的配置中心. 一.启动N ...

  7. SpringCloud Alibaba微服务实战(三) - Nacos服务创建消费者(Feign)

    什么是Feign Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单.使用 Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用 Feign 注解和 ...

  8. 微服务实战(六):选择微服务部署策略

    http://dockone.io/article/1066 微服务实战(六):选择微服务部署策略 [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺 ...

  9. .net core 微服务_.NET 微服务实战之负载均衡(上)

    (给DotNet加星标,提升.Net技能) 转自:陈珙cnblogs.com/skychen1218/p/13327965.html 系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术 ...

最新文章

  1. vSphere PowerCLI安装及命令
  2. java调用spark_spark中的并行方法调用以及传递方法中使用spark会话
  3. 转:c/c++ 运行库
  4. 增加话务系统功能感想
  5. windows下用pycharm安装tensorflow简易教程
  6. 梭子鱼智能安全透视平台揭穿精密伪装威胁
  7. XCode的使用心得
  8. 【玩转Eclipse】——eclipse实现代码块折叠-类似于VS中的#region……#endregion
  9. oracle 查询过去一个星期的数据_过去一星期,最懂我的居然是一个表情包
  10. java 各种数据类型的互相转换
  11. 能够生成动态图片的R模块:rCharts
  12. [转载] Java的访问修饰符、非访问修饰符分类详细总结以及修饰符用途总结
  13. 命令登陆mysql数据库_命令操作Mysql数据库
  14. 赖美云的认证照_火箭少女最新路透照出炉:吴宣仪赖美云魅力十足,张紫宁傅菁凭颜值圈粉...
  15. FX3 DMA生产者消费者ID代表的含义
  16. Teamviewer被检查成商业用途的解决方法
  17. 《深入理解C指针》——认识指针
  18. Mysql 新增分区,删除分区,合并分区
  19. 依赖注入和反转控制的区别
  20. 那些主流的淘宝客引流方法有哪些?

热门文章

  1. 使用Caffe基于cifar10进行物体识别
  2. Ruby的Singleton method
  3. Java项目:食品溯源系统(java+Springboot+Maven+mybatis+Vue+mysql+wd)
  4. 华南理工计算机基础知识题,华南理工_计算机应用基础_随堂练习答案(2017年)
  5. 腾讯云 短信服务 【学习记录 】
  6. 第8章系统服务(简易音频播放器的实现)
  7. android专栏目录
  8. * core-js/modules/es6.array.fill in ./node_modules/_cache-loader@2.0.1@cache-loader/dist/cjs.js??ref
  9. iOS 三种类型的Block
  10. 利用runtime实现KVO