- 之前一直使用的是基于dubbo-zookeeper的微服务架构,今天开始学习基于springcloud的微服务架构,首先是springcloud简介
- springcloud官网 https://spring.io/projects/spring-cloud/
- dubbo和springcloud有很多共同点也有很多不同之处,dubbo在进行服务调用时是基于RPC(远程过程调用Remote Procedure Call),默认的通讯协议是dubbo,底层则是使用netty进行请求,springcloud是基于REST API,在服务的调用上更为方便,容错机制也提供有像Hystrix熔断器等等
- 初见
springcloud相比于dubbo在框架的搭建要简单许多,idea编辑器也对springcloud有完善的初始化模块,对于一个初次体验的人简直不要太友好
一些常用的组件都会在Spring Initializr中看到,搭建起来也是比较方便 - 框架搭建过程
服务发现(eureka),服务的注册中心,作用:服务治理,服务发现;
新建一个module,选择 spring Initializr
模块名称,包路径名称,java版本选择;
选择springcloud discovery,选择eureka server,一路next
package com.sunyw.xyz.eureka;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
private static Log log = LogFactory.getLog(EurekaApplication.class);
public static void main(String[] args) {
log.info("注册中心开始启动....loading");
SpringApplication.run(EurekaApplication.class, args);
}
}
服务启动类增加@EnableEurekaServer,标识当前为服务注册,配置文件
server:
port: 9000
spring:
application:
name: eureka
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
default-zone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance:
hostname: localhost
register-with-eureka设置不注册本身,fetch-registry是否获取其他服务地址,配置完成后启动,访问http://127.0.0.1/port
eureka的管理面板
- 服务熔断-hystrix
创建服务模板与之前的区别在于选择初始化时选择springcloud circuit breaker 熔断器,hystrix
选择hystrix,pom文件中别忘记加上eureka的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 配置文件
server:
port: 9003
spring:
application:
name: hystrix
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/,http://127.0.0.1:8999/eurekaby/
instance:
ip-address: true
- 启动类中加上@EnableHystrixDashboard
package com.sunyw.xyz.hystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard
@EnableEurekaClient
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
- 下面创建一个服务提供者和服务调用者
package com.sunyw.xyz.product;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
@EnableEurekaClient 开始注册中心连接,配置文件@EnableFeignClients,开启fegin调用
server:
port: 9001
spring:
application:
name: product
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/,http://127.0.0.1:8999/eurekaby/
instance:
ip-address: true
feign:
hystrix:
enabled: true
- 多注册中心地址可用,隔开,然后创建一个web接口
package com.sunyw.xyz.product.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ProductController {
@RequestMapping(value = "/word")
public String getWord(@RequestParam String name) {
return "Word";
}
}
- 服务消费者,配置与上方一直,修改端口号和服务名称
package com.sunyw.xyz.customer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class CustomerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
}
- 消费者配置文件
server:
port: 9004
spring:
application:
name: customer
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9000/eureka/,http://127.0.0.1:8999/eurekaby/
instance:
ip-address: true
feign:
hystrix:
enabled: true
- fegin的服务调用是基于服务名称加接口地址进行调用的
package com.sunyw.xyz.customer.controller;
import com.sunyw.xyz.customer.service.CustomerInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class CustomerController {
@Autowired
private CustomerInterface customerInterface;
@RequestMapping("/getWord")
public String getWord(@RequestParam String name) {
return customerInterface.getName(name);
}
}
package com.sunyw.xyz.customer.service;
import com.sunyw.xyz.customer.service.impl.CustomerInterfaceImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "product", fallback = CustomerInterfaceImpl.class)
public interface CustomerInterface {
@RequestMapping("/api/word")
String getName(@RequestParam(value = "name") String name);
}
package com.sunyw.xyz.customer.service.impl;
import com.sunyw.xyz.customer.service.CustomerInterface;
import org.springframework.stereotype.Component;
/**
* @Description: 服务熔断
* @Author: sunyw
* @CreateDate: 2020/8/24 21:55
* @UpdateUser: sunyw
* @UpdateDate: 2020/8/24 21:55
* @UpdateRemark: 修改内容
* @Version: 1.0
*/
@Component
public class CustomerInterfaceImpl implements CustomerInterface {
@Override
public String getName(String name) {
return "Fegin调用失败";
}
}
- 测试
- 测试熔断异常
- 暂时这么多,代码地址:https://gitee.com/sunyaowei/springcloud-ex.git