1.为什么需要springcloud
1.单体应用架构 规模大有问题
虽然可以分模块,但是最终打成以一个war运行
2.单体架构的缺点:
①编译难,部署难,测试难
代码量变多,即使更改一行代码,也需花大量时间编译,部署前要编译打包,解压等所以部署难,部署完了还要测试所以测试难。
②技术选择难
在变得越来越大的同时,我们的应用所使用的技术也会变得越来越多。这些技术有些是不兼容的,就比如在一个项目中大范围地混合使用C++和Java几乎是不可能的事情。在这种情况下,我们就需要抛弃对某些不兼容技术的使用,而选择一种不是那么适合的技术来实现特定的功能。
③扩展难
3.微服务架构
1.解决单体应用的不足
2.什么时微服务架构:
把一个系统拆分为多个独立技术选型,独立开发,独立部署,独立运维的微服务
3.使用场景:
适合规模比较大的项目
4.微服务架构spring解决方案
1.开发单个服务springboot
2.协调多个服务用springcloud http协议
2.什么时springcloud
1.是sping提供一个服务治理框架
2.有很多组件组成,核心是五大神兽
1.服务注册发现——Netflix Eureka : 注册所有微服务的通信地址
2.客服端负载均衡——Netflix Ribbon\Feign :服务之间的调用问题
3.断路器——Netflix Hystrix :解决微服务故障问题,微服务的隔离
4.服务网关——Netflix Zuul :微服务的统一入口
5.分布式配置——Spring Cloud Config :统一管理微服务的配置文件
3.springcloud的搭建
1.搭建一个Parent
作用:限定springboot版本-开发单个服务
限定springcloud版本-协调多个服务
1.配置pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<springboot.version>2.0.5.RELEASE</springboot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.搭建一个放公共代码的项目
3.搭建服务提供者
1.导入jar
<dependencies>
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<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>
</dependency>
</dependencies>
2.yml配置
server:
port: 8001
spring:
application:
name: PRODUCT-SERVICE #服务名
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #告诉服务提供者要把服务注册到哪儿
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
3.入口类
@SpringBootApplication
public class UserProviderApplication_8001 {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication_8001.class);
}
}
4.写服务代码
@RestController
@RequestMapping("/product")
public class ProductController {
//通过id获取product restfull
//@RequestMapping("/{id}")
//@RequestMapping(value = "/{id}",method = RequestMethod.GET) //调用的时候传递的product/1
@GetMapping("/{id}")
// @PostMapping
// @DeleteMapping
// @PutMapping q
public sx.domain.Product getProduct(@PathVariable(name = "id")Long id){
Product product = new Product();
product.setId(id);
product.setName("东西");
return product;
}
}
4.服务消费者
1.导入jar
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<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>
</dependency>
2.配置yml文件
server:
port: 9001
spring:
application:
name: PRODUCT-SERVCIE #服务名
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #告诉服务提供者要把服务注册到哪儿
instance:
prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找
3.入口类
@SpringBootApplication
@EnableEurekaClient
public class OrderSerivce9001Application {
public static void main(String[] args) {
SpringApplication.run(OrderSerivce9001Application.class,args);
}
}
4.调用接口
@Configuration // <beans></beans>
public class CfgBean {
@Bean //<bean class="org.springframework.web.client.RestTemplate"></bean>
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
@RestController
@RequestMapping("/order")
public class OrderController {
//下面是写死的
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
//暴露通过id 远程查询product的接口
@GetMapping("/product/{id}")
public sx.domain.Product getProductById(@PathVariable("id")Long id){
//获取时服务名要小写
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
//现在来说服务id为product-serivce只有一个
ServiceInstance serviceInstance = instances.get(0);
//拼接地址 http://localhost:8001/product/1
String url="http://"+serviceInstance.getHost()+":"
+serviceInstance.getPort()+"/product/"+id;
return restTemplate.getForObject(url, sx.domain.Product.class);
}
}
4.springcloud Eureka
1.什么是springcloud Eureka
服务注册中心,c/s架构模式,EurekaServer,EurekaClient(服务提供者注册服务,服务消费者获取服务列表完成)
2.搭建Eureka (单机)
1.导入jar
<!--springboot支持-->
<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>
</dependency>
<!--Eureka服务端支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.yml配置
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false #是否要注册到eureka
fetchRegistry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
3.入口类
@SpringBootApplication
@EnableEurekaServer //标识是eureka服务端
public class EnrekaServerApplication_7001 {
public static void main(String[] args) {
SpringApplication.run(EnrekaServerApplication_7001.class);
}
}
3.搭建Eureka (集群)
1.先把之前搭建的单机copy几个
2.配置yml
server:
port: 7001
eureka:
instance:
hostname: eureka-7001.com #集群
client:
register-with-eureka: false #是否要注册到eureka
fetch-registry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://eureka-7003.com:7003/eureka/ #集群配置,配置除了自己以外,多个用逗号分隔
server:
port: 7003
eureka:
instance:
hostname: eureka-7003.com #集群
client:
register-with-eureka: false #是否要注册到eureka
fetch-registry: false #表示是否从Eureka Server获取注册信息
serviceUrl:
defaultZone: http://eureka-7001.com:7001/eureka/ #集群配置
3.服务消费者的,服务提供者
defaultZone修改为集群的地址,多个用逗号隔开
defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7003.com:7003/eureka
4.映射hosts
添加这两句
127.0.0.1 eureka-7001.com
127.0.0.1 eureka-7002.com
注意:
这个的话可以看看是不是有端口写错了
eureka.client.service to java.util.Map可能是yml的defaultZone前面没有空格导致格式不对