在Java开发分布式领域,有阿里巴巴的dubbo和springCloud的两种比较出名,但是随着springBoot这种开箱即用的模式广泛传播。springCloud越来越广泛。所以掌握springCloud现在也成为必备的东西。
确定版本
下面我们就基于如下版本开发。
// 定义变量
springBootVersion = '2.0.1.RELEASE'
springCloudVersion = 'Finchley.RELEASE'
创建项目
首先创建一个项目。File->New->Project 我们选择Gradle版本,一步一步创建好。
图一
图二
接下来在cloud-project下创建项目的Module。选中cloud-project->new->Module,下面操作,如图一,图二。创建相应的Module
图三:cloud-project结构图
项目全局的build.gradle
group 'com.zhm'
version '1.0'
buildscript {
ext {
// 定义变量
springBootVersion = '2.0.1.RELEASE'
springCloudVersion = 'Finchley.RELEASE'
}
repositories {
mavenLocal()
maven { url "http://repo1.maven.org/maven2" }
maven { url "https://plugins.gradle.org/m2/" }
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
allprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencyManagement {
imports {
// 解决cloud零散jar的版本问题
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
// 统一移除jar
/*configurations {
all*.exclude module: 'spring-boot-starter-logging'
all*.exclude module: 'logback-classic'
}*/
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-test')
// compile ':spring-cloud-starter-config'
// compile ':spring-cloud-starter-eureka'
// compile(group: 'com.qcloud', name: 'cos_api', version:'4.4') {
// exclude(module: 'slf4j-log4j12')
// }
}
}
Common层
图三中1是common层。其中是存储一些JavaBean,如Result
package com.zhm;
/**
* Created by 赵红明 on 2019/12/13.
*/
public class Result {
public static Result build(){
return new Result();
}
public static Result success(){
return new Result(true, Code.OK, null);
}
public static Result success(String message){
return new Result(true, Code.OK, message);
}
public static Result success(String message, Object data){
return new Result(true, Code.OK, message).setData(data);
}
public static Result error(){
return new Result(true, Code.ERROR, null);
}
public static Result error(String message){
return new Result(true, Code.ERROR, message);
}
public static Result error(String message, Object data){
return new Result(true, Code.ERROR, message).setData(data);
}
// 是否成功
private boolean flag;
// 返回码
private Integer code;
// 返回信息
private String message;
// 返回数据
private Object data;
public Result() {
}
public Result(boolean flag, Integer code, String message) {
this.flag = flag;
this.code = code;
this.message = message;
}
public Result(boolean flag, Integer code, String message, Object data) {
this.flag = flag;
this.code = code;
this.message = message;
this.data = data;
}
public boolean isFlag() {
return flag;
}
public Result setFlag(boolean flag) {
this.flag = flag;
return this;
}
public Integer getCode() {
return code;
}
public Result setCode(Integer code) {
this.code = code;
return this;
}
public String getMessage() {
return message;
}
public Result setMessage(String message) {
this.message = message;
return this;
}
public Object getData() {
return data;
}
public Result setData(Object data) {
this.data = data;
return this;
}
@Override
public String toString() {
return "Result{" +
"flag=" + flag +
", code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
public class Code {
//成功
public static final int OK = 20000;
//失败
public static final int ERROR = 20001;
//用户名或密码错误
public static final int LOGINERROR = 20002;
//权限不足
public static final int ACCESSERROR = 20003;
//远程调用失败
public static final int REMOTEERROR = 20004;
//重复操作
public static final int REPERROR = 20005;
}
}
eurka服务注册中心
图三中2是服务注册中心,只需要一个注解@EnableEurekaServer,这个注解需要在springboot工程的启动application类上加:
package com.zhm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author houyu
* @createTime 2019/4/5 23:33
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
所以build.gradle只需要添加
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')
即可。eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳(因此可以在内存中完成),在默认情况下erureka server也是一个eureka client ,必须要指定一个 server。eureka server的配置文件appication.properties
server.port=6869
spring.application.name=eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://127.0.0.1:${server.port}/eureka/
通过eureka.client.register-with-eureka:false和fetch-registry:false来表明自己是一个eureka server.
eureka server 是有界面的,启动工程,打开浏览器访问: http://localhost:6869,界面如下
No application available 没有服务被发现 ……^_^ 因为没有注册服务当然不可能有服务被发现了。
client服务提供者
图三中3是服务提供者,当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。
build.gradle
dependencies {
compile project(':common') //从common中获取javabean
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
compile('dom4j:dom4j')
}
当然少不了。Application
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //添加@EnableDiscoveryClient注解后,项目就具有了服务注册的功能。启动工程后,就可以在注册中心的页面看到
@EnableFeignClients //启用feign进行远程调用
public class ClientApplication {
public static void main(){
SpringApplication.run(ClientApplication.class);
}
}
接下来,需要相应的controller。service.serviceImpl不多说了,直接上代码
Test.controller
@RestController
public class TestController {
@Autowired
private UserService userService;
@RequestMapping("/test/user/{id}")
public Result hello(@PathVariable("id") String id){
Result hello = userService.hello(id);
return hello.setData("我是调用其他微服务添加的数据.");
}
}
UserService
@FeignClient(value = "user",fallback = UserServiceImpl.class,path = "/user")
public interface UserService {
@RequestMapping(value = "/{id}")
public Result hello(@PathVariable("id")String id);
}
UserServiceImpl
public class UserServiceImpl implements UserService{
@Override
public Result hello(String id) {
return Result.error("调用失败,启动熔断器机制");
}
}
当然需要application.properties
server.port=8081
spring.application.name=client
eureka.client.service-url.defaultZone=http://127.0.0.1:6869/eureka/
eureka.client.service-url.instance.prefer-ip-address=true
feign.hystrix.enabled=true
由此,服务提供者就准备好了。
Server服务消费者
图三中的4是服务消费者
build.gradle如下
compile project(':common')
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
appliactin.properties
server.port=8080
spring.application.name=server
eureka.client.service-url.defaultZone=http://127.0.0.1:6869/eureka/
eureka.client.service-url.instance.prefer-ip-address=true
由于是服务消费者启动时,只需要EnableEurekaClient就行。
@SpringBootApplication
@EnableEurekaClient
public class ServerApplication {
public static void main(String[] args){
SpringApplication.run(ServerApplication.class);
}
}
最后,消费者的controller如下。
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/{id}")
public Result hello(@PathVariable("id") String id){
return Result.success("userId:" + id);
}
}
把所有的项目启动,首先启动注册中心。接着启动生产者,最后启动消费者。
如果想学的更加详细,可参考。springCloud学习