十次方day07(SpringCloud之出入江湖)

一.springCloud的简介

1.springCloud?

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、熔断器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并
没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

2.springboot和springcloud之间的关系

Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;Spring Boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现,可以不基于Spring Boot吗?不可以。
Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。

3.常用的springcloud的组件

服务发现——Netflix Eureka
服务调用——Netflix Feign
熔断器——Netflix Hystrix
服务网关——Netflix Zuul
分布式配置——Spring Cloud Config
消息总线 —— Spring Cloud Bus

4.springcloud和double对比

Dubbo只是实现了服务治理,而Spring Cloud下面有17个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面,一定程度来说,Dubbo只是Spring CloudNetflix中的一个子集。

十次方day07(SpringCloud之出入江湖)_第1张图片

唯一Dubbo的一点优势就是,调用方式是rpc,底层是通过二进制传输的,效率极高,而springcloud是通过rest API进行传输的效率低

 

二.服务发现组件Eureka

十次方day07(SpringCloud之出入江湖)_第2张图片

Eureka服务端的开发

开发步骤:

1.创建Eureka server 工程

2.创建启动类,在启动类上添加注解@EnableEurekaServer

3.提供配置文件,在配置文件中指定EurekaServer的相关配置

4.启动工程,访问6868  端口  查询EurekaServer的注册端口号

十次方day07(SpringCloud之出入江湖)_第3张图片

十次方day07(SpringCloud之出入江湖)_第4张图片

注意:在父工程中导入springcloud版本

十次方day07(SpringCloud之出入江湖)_第5张图片

启动localhost:6868

十次方day07(SpringCloud之出入江湖)_第6张图片

将业务微服务注册到Eureka中

启动类上添加注解:

@EnableEurekaClient

配置文件

保护模式:

Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)

三.Feign实现服务之间的调用

服务间的调用:

前提:必须将服务提供者,服务调用者注册到Eureka Server

 

1、目前项目提供RestApi,采用发送http请求请求目标微服务,弊端:维护多个ip port

2、解决:使用Feign简化开发--通过接口产生代理对象(发送http请求,请求ip地址端口从EurekaServerl

测试通过问答微服务调用基础微服务

1.服务的提供者,提供正确的restAPI

2.服务调用者,映入feign,启动类上添加注解@EnableFeignClient

3.创建接口

4.需要调用接口注入产生代理对象即可

在问答中添加feign

启动类添加注解:

编写接口

十次方day07(SpringCloud之出入江湖)_第7张图片

测试可以查询数据

实现服务的之间的调用

负载均衡:

在feign框架中包含的组件Ribbon实现微服务的负载均衡

十次方day07(SpringCloud之出入江湖)_第8张图片

十次方day07(SpringCloud之出入江湖)_第9张图片

四.交友微服务的开发

需求分析:

十次方day07(SpringCloud之出入江湖)_第10张图片

十次方day07(SpringCloud之出入江湖)_第11张图片

十次方day07(SpringCloud之出入江湖)_第12张图片

1.单向添加好友,和添加不喜欢的好友

/**
     * @param friendid 对方好友id
     * @param type 1:喜欢(关注)好友 2:不喜欢(屏蔽好友)
     * @return
     */
    @PutMapping("/like/{friendid}/{type}")
    public Result addFriend(@PathVariable String friendid, @PathVariable String type){

        //问题 如何获取当前用户id
        //用户登陆成功后,返回jwt token。解析token获取用户id
        Claims claims = (Claims) request.getAttribute("claims");
        if(claims!=null && claims.get("roles").equals("user")){
            String userid = claims.getId();
            if(type.equals("1")){
                friendService.addFriend(userid, friendid);
                return new Result(true, StatusCode.OK, "添加好友成功");
            }else{
                //不喜欢此好友,好友推荐列表中不再出现
               friendService.addNofriend(userid, friendid);
                return new Result(true, StatusCode.OK, "屏蔽好友成功");
            }
        }

        return new Result(false, StatusCode.ACCESSRROR, "无权操作");
    }

service层

    @Autowired
    private FriendDao friendDao;
    @Autowired
    private NoFriendDao noFriendDao;
    //单向添加好友
    @Transactional
    public void  addFriend(String userid, String friendid) {
        Friend friend = new Friend();
        friend.setUserid(userid);
        friend.setFriendid(friendid);
        friend.setIslike("0");//单向喜欢
        friendDao.save(friend);
        //查询是对方好友是否关注我

      int count =   friendDao.selectCount(friendid,userid);
      if (count > 0){
          //互粉状态
          //修改双方的状态islike
          friendDao.updateIsLike(friendid,userid,"1");
          friendDao.updateIsLike(userid,friendid,"1");
      }

    }

    /**
     * 添加不喜欢的好友
     * @param userid
     * @param friendid
     */
    public void addNofriend(String userid, String friendid) {
        NoFriend noFriend = new NoFriend();
        noFriend.setFriendid(friendid);
        noFriend.setUserid(userid);
        noFriendDao.save(noFriend);
    }

dao层

public interface FriendDao extends JpaRepository {
    @Query("select count(*) from Friend f where f.userid = ?1 and f.friendid = ?2")
    int selectCount(String friendid, String userid);
    @Query("update Friend  f set f.islike = ?3 where f.userid = ?2 and f.friendid = ?1")
    @Modifying
    void updateIsLike(String friendid, String userid, String s);
}

2.删除好友的实现:

实现添加到nofriend中并且在在更改对方的好友的islike为0

/**
     * 删除好友的实现
     */
    @DeleteMapping("/{friendid}")
    public Result delete(@PathVariable String friendid){
        Claims claims = (Claims) request.getAttribute("claims");
        if(claims!=null && claims.get("roles").equals("user")){
            String userid = claims.getId();
            friendService.deleteFriend(userid,friendid);
            return new Result(true, StatusCode.OK,"删除成功");
        }

        return new Result(false, StatusCode.ACCESSRROR, "无权操作");
    }
 /**
     * 删除好友
     * @param userid
     * @param friendid
     */
    @Transactional
    public void deleteFriend(String userid, String friendid) {
        friendDao.deleteFriend(userid,friendid);
        friendDao.updateIsLike(friendid,userid,"0");
        addNofriend(userid,friendid);//想不喜欢的表中添加记录
    }

 

 @Query("delete from Friend f where f.userid = ?1 and f.friendid = ?2")
    void deleteFriend(String userid, String friendid);

3.用户微服务的粉丝数和关注数的改变

在user微服务模块

/**
	 * 添加粉丝数
	 */
	@PostMapping("/incfans/{userid}/{x}")
	public void incFanscount(@PathVariable String userid,@PathVariable int x){
		userService.incFanscount(userid,x);
	}
	/**
	 * 添加关注数
	 */
	@PostMapping("/incfollow/{userid}/{x}")
	public void incFollowercount(@PathVariable String userid,@PathVariable int x){
		userService.incFollowcount(userid,x);
	}
	
/**
     * 跟改粉丝数
     */
    @Modifying
    @Query("update User u set u.fanscount = u.fanscount+?2 where u.id=?1")
    public void incFanscount(String userid,int x);

    /**
     * 更改关注数
     */
    @Modifying
    @Query("update User u set u.followcount = u.followcount + ?2 where u.id = ?1")
    public void incFollowcount(String userid,int x);

我们在friend我服务模块中添加接口,用来代理use微服务中的方法

@FeignClient("tensquare-user")
public interface UserClient {
    /**
     * 增加粉丝数据
     */
    @PostMapping("/user/incfans/{userid}/{x}")
    public void incFanscount(@PathVariable("userid") String userid,@PathVariable("x") int x);
    /**
     * 增加关注数
     */
   @PostMapping("/user/incfollow/{userid}/{x}")
    public void incFollowercount(@PathVariable("userid") String userid,@PathVariable("x") int x);
}

注意:添加@FignClient注解用于指定代理的用户模块

@PathVaribale中属性值,必须添加,不然就会报错

在friendService的addFriend方法中

//增加关注数和粉丝数
  userClient.incFanscount(userid,1);
  userClient.incFollowercount(friendid,1);

在deleteService方法减少粉丝和关注数

userClient.incFanscount(userid,-1);
userClient.incFollowercount(friendid,-1);

注意:这些操作一定要在方法上添加注解

五.面试问题

1.你在项目中那些模块中用到了SpringCloud组件

服务注册组件Eureka 服务发现组件Feign 熔断器 网关 SpringCloudConfig (集中配置
管理) SpringCloudBus(消息总线)

2.你在项目中哪个业务场景使用到微服务间的调用
交友微服务 添加好友,在交友微服务中调用用户微服务的更改粉丝数与关注数的方法。

 

你可能感兴趣的:(Project,交友微服务,Eureka服务的注册,Feign服务之间的调用)