什么是微服务?

微服务就是把原本臃肿的项目的所有模块拆分开来并做到互相没有关联,零耦合,设置可以不使用同一个数据库。比如说:一个项目里有User模块和Order模块,但是User模块和Order模块并没有直接的关系,只是一些数据需要交互,这样就能把两个模块分开,User模块是一个服务,Order模块也是一个服务,两个服务之间可以相互调用。

微服务和分布式的区别是什么?

分布式其实也是一种微服务,他们的本质区别主要体现在“目标”上,就是两种架构要达到什么目的,分布式的目的主要是考虑到服务器等的承受能力或者是成本问题(好的服务器肯定贵),不得不使用多台机器来完成服务的部署,而微服务的目标是让各个模块拆分开来,不会被相互影响,比如某一个模块需要升级或是出现了bug,就不会影响到其他的模块。一句话总结,分布式也是微服务的一种,而微服务是可以在一台机器上的。

微服务面临的问题有哪些?

主要问题有负载均衡(nginx 、ribbon);熔断、限流、降级(hystrix);网关、路由、过滤(zuul);监听服务有没有宕机、服务注册与发现 (eureka 、zk)等一系列问题。Spring-Cloud应运而生,Spring-Cloud将解决这些问题的技术进行了整合封装,也就是说用Spring-Cloud这些问题都可以解决。

微服务与Spring-Cloud的关系是什么?

微服务只是一种项目的架构方式,或者说是一种概念,类似于学过的MVC架构一样,Spring-Cloud只是对这种技术的实现方式。所以说,微服务不只有Spring-cloud这一种实现方式,甚至我们可以自己手写一个微服务。

搭建Spring-Cloud需要特别注意的坑

微服务一般安装什么去分模块 微服务如何划分模块_java


这个是springcloud官网的截图,是springcloud的版本与springboot版本的对应,Springcloud的依赖版本要和springboot的版本严格对应,不然会报错。

带你手写最简单的微服务

在一个项目中新建两个springboot模块,User模块和Power;

微服务一般安装什么去分模块 微服务如何划分模块_微服务一般安装什么去分模块_02


微服务一般安装什么去分模块 微服务如何划分模块_微服务_03


思路:在User模块中调用Power模块中的服务,利用RestTemplate实现两个模块之间的通讯。(这里只用了Controller层节省时间没有调数据库)

User模块:

UserController:写了两个接口,一个是本服务的,另一个是调用Power服务的。

@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/getUser")
    public R getUser(){
        Map<String,Object> map=new HashMap<>();
        map.put("key","user");
        return R.success("返回成功",map);
    }

    @RequestMapping("/getPower")
    public R getPower(){
        return R.success("操作成功",restTemplate.getForObject("http://localhost:5001/getPower",Object.class));
    }
}

AppConfig:配置端口号;

@ComponentScan("com")
@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory(){
        TomcatServletWebServerFactory tomcatServletWebServerFactory=new TomcatServletWebServerFactory();
        tomcatServletWebServerFactory.setPort(5000);
        return tomcatServletWebServerFactory;
    }
}

上边的UserController中用到的R是一个结果的封装类,主要将返回结果进行了封装。
Power模块:
PowerController:

@RestController
public class PowerController {

    @RequestMapping("/getPower")
    public Object getPower(){
        Map<String,Object> map=new HashMap<>();
        map.put("key","power");
        return map;
    }
}

AppConfig:配置端口号;

@ComponentScan("com")
@Configuration
public class AppConfig {
    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory(){
        TomcatServletWebServerFactory tomcatServletWebServerFactory=new TomcatServletWebServerFactory();
        tomcatServletWebServerFactory.setPort(5001);
        return tomcatServletWebServerFactory;
    }
}

然后启动两个服务,访问http://localhost:5000/getUser;

微服务一般安装什么去分模块 微服务如何划分模块_微服务_04


访问http://localhost:5000/getPower;

微服务一般安装什么去分模块 微服务如何划分模块_User_05


R.java 结果封装类(可以在随便的项目中使用):

package com.sitech.cloud.util;
import java.util.HashMap;
public class R extends HashMap{
    public static  String SUCCESS_CODE="200";
    public static String ERROR_CODE="500";
    public static String DATA_KEY = "data";
    public static String MSG_KEY = "msg";

    private R(){

    }
    public R set(String key, Object object){
        super.put(key,object);
        return  this;
    }
    private  static R ok(){
        return new R();
    }
    public static R success(){
        return R.ok().set("code", R.SUCCESS_CODE).set(R.MSG_KEY,"操作成功");
    }
    public static R success(String msg){
        return R.ok().set("code", R.SUCCESS_CODE).set(R.MSG_KEY,msg);
    }
    public static R success(String msg, Object object){
       return R.ok().set("code", R.SUCCESS_CODE).set(R.MSG_KEY,msg).set(R.DATA_KEY,object);
    }
    public R data(Object obj){
        return this.set("data",obj);
    }
    public static R error(){
        return R.ok().set(R.MSG_KEY,"操作失败").set("code", R.ERROR_CODE);
    }
    public static R error(String msg){
        return R.ok().set(R.MSG_KEY,msg).set("code", R.ERROR_CODE);
    }
    public static R error(String msg, Object object){
        return R.ok().set(R.MSG_KEY,msg).set(R.DATA_KEY,object).set("code", R.ERROR_CODE);
    }
}