互联网框架day05(springcloud eureka ribbon)

1.order-user系统的整合
1.1订单支付
通过访问订单支付功能,订单系统发起代码内部的HTTP请求到用户系统调用user/update/point
1.2RestTemplate (个人理解相当于前端的Ajax用在了后端中,相当于后端的Ajax)
springmvc的对象,支持REST风格,支持http协议的并发访问(http协议封装成了对象调用的方法)
getForObject get请求
postForObject post 请求
putForObject
deleteForObject

Get
getForObject:返回值是响应体
getForEntity:返回值是响应对象

getForEntity().getBody()==getForObject();
重载方法三个
(url,responseType,Map<String,Object>);
(url,responseType,Object…);
(url,responseType);
Post
postForObject:返回值是响应体
postForEntity:返回值是响应对象
postForEntity().getBody()==postForObject();和get的区别就是post可以将请求体中封装一些内容
(url,request,responseType,param);
request:Object;类型请求体中的数据可以是代码中的对象,user对象,order(一json字符串格式传递给后端的服务器,接收请求体中的数据)

总结:
restTemplate封装的http协议的对象可以实现不同的请求方式,不同的传参格式,发起向服务器的请求,接收响应或者响应体数据

2.分布式的order_user系统的问题
没有管理的结构的引入,每个系统之间都要通过nginx这种技术的静态文件维持访问调用的关系
独立的系统越多,静态文件配置的内容就越多形成了强耦合—>频繁的大量修改静态配置文件(因为可能会遇到宕机等问题,必须修改配置文件)

3.微服务架构
3.1什么是微服务
3.2什么是微服务架构
3.3什么是微服务springcloud
4.springcloud
基于springboot的自动配置实现的微服务框架,可以在引入依赖之后,利用自动配置的机制,实现springcloud不同组件的自动配置

springboot整合纵向拆分order-user
1.订单功能
1.1接口文件
请求地址 /order/pay
请求参数 String orderId
返回数据 1/0成功和失败
1.2代码编写
Ordercontroller
OrderService()(实现支付逻辑,实现调用user的update接口)
OrderMapper
OrderMapper.xml
Order/User

1.3RestTemplate
封装了底层Http协议,可以从代码中发起http请求
测试案例
通过RestTemplate访问一个网站 (京东)

nginx配置修改
在这里插入图片描述
源码:

package cn.tedu.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.tedu.service.OrderService;

@RestController
public class OrderController {
	@Autowired
	private OrderService orderService;
	//订单支付
	@RequestMapping("order/pay")
	public Integer orderPay(String orderId){
		try {
			orderService.orderPay(orderId);
			return 1;
		} catch (Exception e) {
			//给自己展示异常
			e.printStackTrace();
			return 0;
		}
	}
}

package cn.tedu.domain;

public class Order {
	private String orderId;
	private Integer orderMoney;
	private Integer userId;
	public Order(String orderId, Integer orderMoney, Integer userId) {
		super();
		this.orderId = orderId;
		this.orderMoney = orderMoney;
		this.userId = userId;
	}
	public Order() {
		super();
	}
	public String getOrderId() {
		return orderId;
	}
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}
	public Integer getOrderMoney() {
		return orderMoney;
	}
	public void setOrderMoney(Integer orderMoney) {
		this.orderMoney = orderMoney;
	}
	public Integer getUserId() {
		return userId;
	}
	public void setUserId(Integer userId) {
		this.userId = userId;
	}
	@Override
	public String toString() {
		return "Order [orderId=" + orderId + ", orderMoney=" + orderMoney + ", userId=" + userId + "]";
	}
	
}

package cn.tedu.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import cn.tedu.domain.Order;
import cn.tedu.mapper.OrderMapper;

@Service
public class OrderService {
	@Autowired 
	private OrderMapper orderMapper;
	public void orderPay(String orderId) {
		//查询order对象,获取useId和orderMoney的数据
		Order order=orderMapper.selectOrderById(orderId);
		//支付逻辑中可以实现打折,活动,确定支付的真正金额
		System.out.print("用户:"+order.getUserId()+
				"支付金额:"+order.getOrderMoney());
		//TODO想办法 将参数userid  orderMoney封装到一个htt请求中,
		//发起请求访问www.ssm.com/user/update/point(交给nginx)
		//RestTemplate
		RestTemplate client=new RestTemplate();
		String url="http://www.ssm.com/user/update/point?userId="
				+order.getUserId()+"&orderMoney="+order.getOrderMoney();
		//发起代码的请求到接口的url地址
		Integer success = client.getForObject(url, Integer.class);
		if(success==1){
			System.out.println("积分成功");
		}
		if(success==0){
			System.out.println("积分失败");
		}
		
	}

}

package cn.tedu.mapper;

import cn.tedu.domain.Order;

public interface OrderMapper {


	Order selectOrderById(String orderId);
	
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tedu.mapper.OrderMapper">
	<!-- selectUserById -->
	<!-- <select id="selectUserById" parameterType="int" resultType="User">
		select * from t_user where user_id=#{userId};
	</select> -->
	<!--selectOrderById  -->
	<select id="selectOrderById" parameterType="String" resultType="Order">
		select * from t_order where order_id=#{orderId};
	</select>
	<!-- <update id="updateUserPointsById" parameterType="User" >
		update t_user set  points=points+#{points} where user_id=#{userId};
	</update> -->
</mapper>
#8090
server.port=8091
#server.contextPath=/1906
#1906.class-name=big1906
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///easymall?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.typeAliasesPackage=cn.tedu.domain
mybatis.mapperLocations=classpath:mapper/*.xml
mybatis.configuration.mapUnderscoreToCamelCase=true
mybatis.configuration.cacheEnabled=false
#mapperscaner
<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>cn.tedu</groupId>
  <artifactId>springboot-demo1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot-demo1</name>
  <url>http://maven.apache.org</url>
	<!-- 当前工程是一个子工程  继承父工程 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!--web应用的简化依赖starter-web  -->
  	<!--log jackson embed tomcat spring context beans springboot  -->
  	<dependency>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-web</artifactId>
  	</dependency>
  	<!--jdbc协议  -->
  	<dependency>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-jdbc</artifactId>
  	</dependency>
  	<!-- mysql -->
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.0.8</version>
  	</dependency>
  	<!--springboot mybaits  -->
  	<dependency>
  		<groupId>org.mybatis.spring.boot</groupId>
  		<artifactId>mybatis-spring-boot-starter</artifactId>
  		<version>1.3.1</version>
  	</dependency>
  	<!--druid  -->
  	<dependency>
  		<groupId>com.alibaba</groupId>
  		<artifactId>druid</artifactId>
  		<version>1.0.14</version>
  	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

测试代码resttemplate

package cn.tedu.restTemplate.test;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import cn.tedu.domain.User;

//RestTemplate测试案例
public class RestTest {
	@Test
	public void test(){
		RestTemplate client=new RestTemplate();
		//根据封装的方法调用api
		//url:访问的地址
		//responseType:响应体的接收类型
		String responseBody=client.getForObject("https://www.jd.com/", String.class);
		System.out.println(responseBody);
		//api有哪些,如何携带参数
		//访问/user/query/point
		User user=client.getForObject("http://localhost:8090/user/query/point?userId=1",
				//String.class);//json
				User.class);//user对象
		System.out.println(user);
	}
	@Test
	public void test2(){
		RestTemplate client=new RestTemplate();
		//根据封装的方法调用api
		//url:访问的地址
		//responseType:响应体的接收类型
		ResponseEntity<String> response = client.getForEntity("https://www.jd.com/", String.class);
		response.getBody();//==getForObject
		response.getHeaders();//头信息
		//client.getForObject(url, responseType, uriVariables)
		//client.getForObject(url, responseType, uriVariables)
		
		//System.out.println(response);
		Map<String, Object> param=new HashMap<String, Object>();
		param.put("userId", 1);
		param.put("lev", 0);
		//map 类型的api
		String user=client.getForObject("http://localhost:8090/user/query/point?userId={userId}&lev={lev}",
				String.class,param);//user对象
		System.out.println(user);
		//object类型的api
		String user2=client.getForObject("http://localhost:8090/user/query/point?userId={1}&lev={2}&age={3}&name={4}",
				String.class,1,0,"haha","kaka");//user对象
		//将1,0看成一个整体  底层封装成数组Object[]={1,0}
		System.out.println(user2);
	}
	
	@Test
	public void test03(){
		RestTemplate client=new RestTemplate();
//		client.postForObject(url, request, responseType)
//		client.postForEntity(url, request, responseType)
//		client.postForObject(url, request, responseType,param)
//		client.postForEntity(url, request, responseType,Object)
	}
}

最终结构
在这里插入图片描述

微服务架构的由来
庞大的微服务架构,如果一个服务宕机,会引起nginx的维护,修改nginx中的配置,麻烦,需要有一个管理,引出springcloud

微服务的引入(详细)
1.纵向拆分的独立系统的集群的问题
1.1没有引入管理的功能
系统的管理,授权监听,熔断等逻辑都没有引入
1.2静态配置的负载均衡的强耦合
在庞大的纵向拆分的集群中,nginx的静态文件维护负载均衡逻辑,容易出现强耦合
例如:集群中某先节点出现宕机/迁移
可以引入微服务的概念,从架构角度去解决问题
2.微服务框架
2.1微服务
从一个单体项目,从一个功能比较集中的项目中纵向拆分出来独立运行的功能,每个功能的系统—微服务

微:纵向拆分
服务:功能被调用
2.2微服务框架
一个框架技术能够管理大量的拆分的独立的系统,具有监控熔断等功能,这种框架技术—微服务框架
2.3springcloud
轻量级的微服务框架,可以基于springboot的自动配置(减少了自定义的大量代码的编写)实现了多个微服务框架的组件的功能
eureka:服务的治理
ribbon:客户端负载均衡的调用
feign:ribbon是同一种客户端,封装了ribbon
hystrix:熔断器
zuul:网关,微服务唯一对外提供的接口
config:微服务种配置文件的管理者

微服务框架springcloud
微服务框架组件
1.Eureka服务治理组件(管理者)
springcloud中的核心组件,可以实现对整个微服务集群所有节点进行服务的发现,服务的抓取,和服务的监听功能
1.1服务治理的概念中的三个角色
服务注册中心:所有的服务的集中管理角色
服务的提供者:服务提供者会将自己的信息打包(ip,port,服务名称等等),注册,在注册中被注册中心管理和维护(注册)
服务的调用者:可以通过对注册中心的访问,获取服务提供者的信息,从而进行负载均衡的调用(抓取发现)

1.2入门案例服务注册中心
准备一个springboot+springcloud开发环境的工程
pom:继承springboot-parent
dependencyManagement:导入springcloud的所有的依赖

继承springboot

<!--继承springboot  -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>

导入依赖springcloud

  <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement>

导入eureka注册中心的依赖

<!-- 导入eureka -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>

pom

<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>cn.tedu</groupId>
  <artifactId>springcloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-eureka-server</name>
  <url>http://maven.apache.org</url>
  <!--继承springboot  -->
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- 导入eureka -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--导入springcloud  -->
  <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement>
</project>

注意:有时候移除junit版本号很有可能会报大错

application.properties

server.port=8888
#eureka相关配置
##关闭当前配置中心的服务抓取和注册(给注册提供者使用,自己也可以作为注册提供者,在高可用时使用,自己注册自己抓取,这里关闭)
#如果自己用自己注册,需要提供服务名称
spring.application.name=eurekaserver
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
#注册中心的地址,但凡是服务器注册者都需要配置这个地址
#注册者会访问这个地址的接口,携带自己节点的信息注册
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

启动类:
添加一个eureka的注解,就能实现启动加载eureka的自动配置逻辑实现一个web应用中包含一个eurekaserver的进程

package cn.tedu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

//启动类
//springboot
@SpringBootApplication
//rureka注册中心进程启动时需要springboot加载扫描的注解
@EnableEurekaServer
public class StarterEurekaServer {
	public static void main(String[] args) {
		SpringApplication.run(StarterEurekaServer.class, args);
		
	}
}

web页面

在这里插入图片描述

在这里插入图片描述

互联网框架和大数据的关系
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将分析结果传给表象层,(新功能:预测:物流高发预测)

注册中心的作用:
管理注册者的服务信息:
内部接收注册者的请求,注册者携带本机节点的详细参数(ip,port,服务名称)发送给注册中心,eureka接收请求,在内存中存储一个双层map对象 保存所有的内容
在这里插入图片描述
服务的监听超时:
多个注册者同时注册一个服务,相当于一个具体的服务,被一个集群管理接收请求,每60秒钟判断是否有服务提供者的续约,超时达到90秒,一旦满足条件,将会从内存中超时的实例剔除

1.3入门案例的服务提供者
创建一个工程springboot+springcloud可以被调用一个资源访问 /hello,作为一个服务的提供者,必须生成一个服务的名称,service-hi,注册在注册中心。

搭建一个系统springboot+springcloud
(做一个pom拥有springboot springcloud的依赖,然后springcloud的组件去继承这个pom(注意这个父类的pom文件的packing要改为pom类型))

<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>cn.tedu</groupId>
  <artifactId>springcloud-parent-demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <!--继承springboot  -->
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
  </parent>
  <name>springcloud-parent-demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--导入springcloud  -->
  <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement>
</project>

在这里插入图片描述

pom 继承springboot-parent
导入 springcloud dependencies
引入一个依赖 spring-cloud-starter-eureka eureka客户端依赖

<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>cn.tedu</groupId>
  <artifactId>springcloud-eureka-client1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-eureka-client1</name>
  <url>http://maven.apache.org</url>
  <!--继承springcloud-parent  -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>springcloud-parent-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version> -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- eureka客户端依赖 -->
  	<dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-eureka</artifactId>
  	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

starter-eureka-server 服务器端依赖,包含了上述的依赖(spring-cloud-starter-eureka)
(更改后的服务端pom文件)

<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>cn.tedu</groupId>
  <artifactId>springcloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-eureka-server</name>
  <url>http://maven.apache.org</url>
  <!--继承springcloud-parent  -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>springcloud-parent-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version> -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- 导入eureka -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--导入springcloud  -->
  <!-- <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement> -->
</project>

application.properties
端口 9001
服务名称:service-hi
注册/发现 开启(默认开启)
注册地址 8888/eureka

server.port=9001
spring.application.name=service-hi
#eureka.client.registerWithEureka=true
#eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

启动类
添加一个eureka客户端的注解(注册和发现的功能)
调用功能
/hello?name=wang 返回hello *** name

package cn.tedu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//客户端的启动类
@SpringBootApplication
//eureka客户端注解
@EnableEurekaClient
public class StarterEurekaClient1 {
	public static void main(String[] args) {
		SpringApplication.run(StarterEurekaClient1.class, args);
	}
}

高可用的集群注册同一个服务
eureka-client1 eureka-client2
eureka-client2修改3处
server.port=9002
controller 返回值 I am from 9002
启动类StarterEurekaClient2

注册者实现的逻辑
注册:启动后,当前eureka client一旦赋予注册能力
registerWithEureka=true 将会访问注册中心接口
8888/eureka 携带详情信息,注册在注册中心,注册中心以服务名称为key值记录一个当前服务的所有节点信息的map对象
续约:eureka client一旦在注册中心提供注册的信息,将会每三十秒发起一次心跳(heartbeat)请求,告知注册中心,当前实例是存活的。

服务的剔除:
30:客户端发起心跳
60:注册中心,每隔60秒检测一次心跳最后的时间
90:注册中心,检测发现超过90秒没有发起心跳检测,将会把该实例剔除
注册中心的保护机制
在这里插入图片描述
庞大的集群中如果按照正常的逻辑,管理一个微服务集群(一百个服务,每个20节点,2000注册者),超时续约的个数如果在15%以内,eureka注册中心,判断是正常的超时,将会按照剔除逻辑对实例进行内存数据的清除,如果超过15%认为是不正常的超时,将会开启保护机制,一旦开启,所有的服务信息(map对象)不会做任何的剔除,形成对微服务的保护
如果需要观察剔除的现象可以将保护机制关闭,注册中心的配置文件中配置保护机制关闭为false

2.ribbon组件
配合服务治理组件eureka的客户端的发现功能,从注册中心抓取最新的服务注册信息,从而可以在代码内部发起向该服务的访问,使用注册信息中实例的详细信息访问不同的节点实现负载均衡—可以调用服务,支持负载均衡访问的springcloud客户端组件

2.1入门案例ribbon负载均衡调用9001/9002
创建一个具备开发springboot-sprinigcloud功能的maven工程
pom文件继承自定义的parent-demo工程

pom添加依赖
rureka-client(抓取服务)
ribbon的组件相关的依赖
application.properties
9004
服务名称 service-ribbon
抓取服务 /true(默认是开启)
注册url地址:8888/eureka
启动类:
eureka client相关的注解
创建一个springboot框架管理的内存对象
@Bean
@loadBalanced
RestTemplate
在这里插入图片描述
2.2实现一个负载均衡的调用后端服务的service-hi
编写一个ribbon的对外访问的url接口
locahost:9004/hi?name=wang

通过ribbon直接实现负载均衡访问9001/9002
HelloController
HelloService

2.3实现动态添加扩容服务提供者
单独访问ribbon工程,可以使用springcloud的ribbon组件做服务调用服务的功能的测试,对于被调用的服务service-hi,只要启动9003作为扩容的节点,添加到eureka注册中心,注册中心维护的注册信息,将会发生变动

ribbon工程整合了eureka client 可以实现服务的抓取,每30秒重新更新抓取一次服务注册信息的map数据

在这里插入图片描述
在这里插入图片描述
代码整理
先创建一个springcloud项目作为父类,书写pom里边的依赖,方便继承使用
(具体在springcloud工作空间里边的springcloud-parent-demo项目)
pom文件配置

<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>cn.tedu</groupId>
  <artifactId>springcloud-parent-demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <!--继承springboot  -->
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
  </parent>
  <name>springcloud-parent-demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--导入springcloud  -->
  <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement>
</project>

eureka注册中心(服务名称,端口,注册中心接口)
启动类

package cn.tedu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

//启动类
//springboot
@SpringBootApplication
//rureka注册中心进程启动时需要springboot加载扫描的注解
@EnableEurekaServer
public class StarterEurekaServer {
	public static void main(String[] args) {
		SpringApplication.run(StarterEurekaServer.class, args);
		
	}
}

配置类

server.port=8888
#eureka相关配置
##关闭当前配置中心的服务抓取和注册(给注册提供者使用,自己也可以作为注册提供者,在高可用时使用,自己注册自己抓取,这里关闭)
#如果自己用自己注册,需要提供服务名称
spring.application.name=eurekaserver
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=false
#注册中心的地址,但凡是服务器注册者都需要配置这个地址
#注册者会访问这个地址的接口,携带自己节点的信息注册
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka
#关闭保护机制(可以剔除,观察剔除现象)
eureka.server.enable-self-preservation=false

pom

<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>cn.tedu</groupId>
  <artifactId>springcloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-eureka-server</name>
  <url>http://maven.apache.org</url>
  <!--继承springcloud-parent  -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>springcloud-parent-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version> -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- 导入eureka -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--导入springcloud  -->
  <!-- <dependencyManagement>
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.cloud</groupId>
  			<artifactId>spring-cloud-dependencies</artifactId>
  			<version>Edgware.RELEASE</version>
  			<type>pom</type>
  			<scope>import</scope>
  		</dependency>
  	</dependencies>
  </dependencyManagement> -->
</project>

eureka注册者(好几个client1,client2…服务名称可能相同,注册中心接口(固定的),修改端口,修改启动类的类名,方便区别)
启动类

package cn.tedu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//客户端的启动类
@SpringBootApplication
//eureka客户端注解
@EnableEurekaClient
public class StarterEurekaClient1 {
	public static void main(String[] args) {
		SpringApplication.run(StarterEurekaClient1.class, args);
	}
}

配置

server.port=9001
#eureka相关配置
##关闭当前配置中心的服务抓取和注册(给注册提供者使用,自己也可以作为注册提供者,在高可用时使用,自己注册自己抓取,这里关闭)
#如果自己用自己注册,需要提供服务名称
spring.application.name=service-hi
#eureka.client.registerWithEureka=true
#eureka.client.fetchRegistry=true
#注册中心的地址,但凡是服务器注册者都需要配置这个地址
#注册者会访问这个地址的接口,携带自己节点的信息注册
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

pom

<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>cn.tedu</groupId>
  <artifactId>springcloud-eureka-client1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-eureka-client1</name>
  <url>http://maven.apache.org</url>
  <!--继承springcloud-parent  -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>springcloud-parent-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version> -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- eureka客户端依赖 -->
  	<dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-eureka</artifactId>
  	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

控制层

package cn.tedu.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
	@RequestMapping("hello")
	public String sayHi(String name){
		return "hello,"+name+",i am from 9001";
	}
}

ribbon服务调用者(也算是一个注册者client)
启动类(除了启动类,还可以配置负载均衡,不配置为默认轮询,还有随机和权重)

package cn.tedu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

//ribbon的启动类
@SpringBootApplication
@EnableEurekaClient
public class StarterRibbon {
	public static void main(String[] args) {
		SpringApplication.run(StarterRibbon.class, args);
	}
	@Bean
	//负载均衡
	@LoadBalanced
	public RestTemplate initRestTemplate(){
		return new RestTemplate(); 
	}
	//修改自定义的随机负载均衡逻辑
	@Bean
	public IRule initRule(){
		return new RandomRule();
	}
}

控制层

package cn.tedu.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.tedu.service.HelloService;
//访问localhost:9004/hi?name=王老师
@RestController
public class HelloController {
	@Autowired
	private HelloService helloService;
	//客户端调用hi接口
	@RequestMapping("hi")
	public String sayHi(String name){
		return "RIBBON:"+helloService.sayHi(name);
	}
}

服务层(拦截服务名称,解析,url,可以被搜索执行)

package cn.tedu.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

		@Autowired
		private RestTemplate client;//会因为使用的创建过程
		//@Bean+@LoadBalanced注解,ribbon会对restTemplate
		//发送的任何请求做拦截工作,将域名寻找抓取的服务名称做实例
		//节点,将节点的ip:port替换
		public String sayHi(String name){
			//http://service-hi/hello?name=wang  会拦截替换
		 	String sayHi=client.getForObject("http://service-hi/hello?name="+name, String.class);
			return sayHi;
		}

}

配置

server.port=9004
#eureka相关配置
##关闭当前配置中心的服务抓取和注册(给注册提供者使用,自己也可以作为注册提供者,在高可用时使用,自己注册自己抓取,这里关闭)
#如果自己用自己注册,需要提供服务名称
spring.application.name=server-ribbon
#eureka.client.registerWithEureka=true
#eureka.client.fetchRegistry=true
#注册中心的地址,但凡是服务器注册者都需要配置这个地址
#注册者会访问这个地址的接口,携带自己节点的信息注册
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka

pom

<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>cn.tedu</groupId>
  <artifactId>springcloud-ribbon-client</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springcloud-ribbon-client</name>
  <url>http://maven.apache.org</url>
  <!--继承springcloud-parent  -->
  <parent>
		<groupId>cn.tedu</groupId>
		<artifactId>springcloud-parent-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<!-- <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version> -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  	<!-- eureka客户端依赖 -->
  	<dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-eureka</artifactId>
  	</dependency>
    <!--ribbon依赖  -->
    <dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-ribbon</artifactId>
  	</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

2.5ribbon实现负载均衡访问服务的原理
在这里插入图片描述
ribbon具备注册和抓取的能力,启动后会将eureka注册中心的所有map数据抓取到本地存储,每隔30秒更新一次抓取内容
restTemplate的创建过程是通过LoadBalances,ribbon会对当前这个对象的所有请求做拦截处理,LoadBalancerInterceptor
restTemplate发送请求http://service-hi/hello?name=wang
ribbon通过拦截解析了服务名称service-hi
通过抓取的map对象找到service-hi value(三个节点的详细信息)
通过负载均衡对象IRule从3个节点选取一个ip:port拼接到域名所在位置最终发送请求

注意:springcloud中只要是服务调用服务的过程都是通过ribbon+restTemplate实现(zuul feign)

3.order-user系统整合到springcloud(需要再加入一个组件)在这里插入图片描述
最前端的客户端浏览器,如何调用suer order 的功能?zuul
4.zuul网关集群的调用结构
在这里插入图片描述

完成eureka注册中心的高可用

总结:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
访问网址:
http://localhost:9004/hi?name=王老师(通过端口访问ribbon)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值