SpringCloud微服务简介
1、集群
计算机集群简称集群是一种计算机系统,它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作。在某种意义上,他们可以被看作是一台计算机。集群系统中的单个计算机通常称为节点,通常通过局域网连接,但也有其它的可能连接方式。集群计算机通常用来改进单个计算机的计算速度和/或可靠性。一般情况下集群计算机比单个计算机,比如工作站或超级计算机性能价格比要高得多。
2、分布式
分布式系统是一组计算机,通过网络相互连接传递消息与通信后并协调它们的行为而形成的系统。组件之间彼此进行交互以实现一个共同的目标。
分布式服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,服务之间也是通过rpc来交互或者是webservice来交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分布式部署,生产环境下的微服务肯定是分布式部署的,分布式部署的应用不一定是微服务架构的,比如集群部署,它是把相同应用复制到不同服务器上,但是逻辑功能上还是单体应用。
3、微服务
微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
4、区别
1:分布式是指将不同的业务分布在不同的地方。而集群指的是将几台服务器集中在一起,实现同一业务。
2、微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
3、分布式属于微服务,因为
微服务:可多个服务器,也可一个
分布式:必须多个服务器
服务注册和发现-Eureka
1、简介
1、服务启动时会生成服务的基本信息对象InstanceInfo,然后在启动时会register到服务治理中心。
2、注册完成后会从服务治理中心拉取所有的服务信息,缓存在本地。
3、之后服务会被30s(可配置)发送一个心跳信息,续约服务。
4、如果服务治理中心在90s内没有收到一个服务的续约,就会认为服务已经挂了,会把服务注册信息删掉。
5、服务停止前,服务会主动发送一个停止请求,服务治理中心会删除这个服务的信息。
6、如果Eureka Server收到的心跳包不足正常值的85%(可配置)就会进入自我保护模式,在这种模式下,Eureka Server不会删除任何服务信息。
2、服务注册和发现
由Eureka Server提供服务注册和发现
将所需服务注册到服务中心,并使得SpringCloud的其他模块可以通过Eureka Server来发现系统中的微服务并加以调用
3、服务提供和消费
由Eureka Client提供
服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
服务消费方,从Eureka获取注册服务列表,从而能够消费服务。
4、具体示例
1、consumer和provider注册到服务中心,并实现Spring Security
2、consumer通过服务注册中心调用provider的controller完成相应的业务
父项目依赖
pom.xml
<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.my.cloud.test</groupId>
<artifactId>CloudParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<!-- spring cloud依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 公共项目 -->
<dependencies>
<dependency>
<groupId>com.my.cloud</groupId>
<artifactId>cloud-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<modules>
<module>EurekaServerRegister</module>
<module>EurekaClientProvider</module>
<module>EurekaClientConsumer</module>
</modules>
</project>
注册中心配置
pom.xml
<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.my.cloud.test</groupId>
<artifactId>CloudParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>EurekaServerRegister</artifactId>
<dependencies>
<!-- eureka server依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- SpringBoot启动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Security依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
</project>
启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApp extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApp.class, args);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
http.csrf().disable();
//注意:为了可以使用 http://${user}:${password}@${host}:${port}/eureka/ 这种方式登录,所以必须是httpBasic,
// 如果是form方式,不能使用url格式登录
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
配置文件–application.yml
server:
port: 10010
eureka:
client:
register-with-eureka: false
fetch-registry: false
serviceUrl:
defaultZone: http://root:Admin123@127.0.0.1:10010/eureka/
spring:
security:
user:
name: root
password: Admin123
服务提供者配置
pom.xml
<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.my.cloud.test</groupId>
<artifactId>CloudParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>EurekaClientProvider</artifactId>
<dependencies>
<!-- SpringBoot启动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖 -->
<!-- <exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions> -->
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
配置文件
server:
port: 8888
spring:
application:
name: provider
eureka:
client:
registerWithEureka: true
serviceUrl:
#指向服务端地址
#defaultZone: http://127.0.0.1:10010/eureka/
#加security验证后需按如下格式通过验证
defaultZone: http://root:Admin123@127.0.0.1:10010/eureka/
启动类
@SpringBootApplication
@EnableEurekaClient
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
}
Controller
@RestController
@RequestMapping("provider")
public class ProviderController {
/*此处必须为get*/
@GetMapping("/getMsg")
public String returnToConsumer() {
return "服务提供者返回的消息";
}
}
服务消费者配置
pom.xml
<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.my.cloud.test</groupId>
<artifactId>CloudParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>EurekaClientConsumer</artifactId>
<dependencies>
<!-- SpringBoot启动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖 -->
<!-- <exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions> -->
</dependency>
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
配置文件
server:
port: 9999
spring:
application:
name: consumer
eureka:
client:
enabled: true
registerWithEureka: true
serviceUrl:
defaultZone: http://root:Admin123@127.0.0.1:10010/eureka/
#defaultZone: http://127.0.0.1:10010/eureka/
启动类
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
/*RestTemplate必须手动来注入,否责使用时无法用@Autowired自动注入*/
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(180000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
}
Controller
@RestController
@RequestMapping("consumer")
public class ConsumerController {
/*根据服务名获取服务请求路径*/
@Autowired
private EurekaClient eurekaClient;
/*根据路径发送请求*/
@Autowired
private RestTemplate restTemplate;
@PostMapping("/getMsg")
public void getProvideMsg() {
/*provider必须为Get请求*/
InstanceInfo instance = eurekaClient.getNextServerFromEureka("provider",false);
String msg = restTemplate.getForObject(instance.getHomePageUrl()+"/provider/getMsg", new String().getClass());
System.out.println(msg);
}
}