上次有人说部署单个springboot项目和ssm写的非常的简单可以写一篇docker部署微服务的结构的文章的吗

安排

什么是微服务?

微服务架构是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序

都在自己的进程中运行,采用一组服务的方式来构建一个应用,服务独立部署

在不同的进程中,不同服务通过一些轻量级交互机制来通信的架构思路。

独立性

在开发层面,每个微服务基本上都是各自独立的项目(project),而对

应各自独立项目的研发团队基本上也是独立对应,这样的结构保证了微服务

的并行研发,并且各自快速迭代,不会因为所有研发都投入一个近乎

单点的项目,从而造成开发阶段的瓶颈。开发阶段的独立,保证了微

服务的研发可以高效进行。

可扩展性

我们可以快速地添加服务集群的实例,提升整个微服务集群的服务

能力,而在传统 Monolith 模式下,为了能够提升服务能力,

很多时候必须强化和扩展单一结点的服务能力来达成。如果单结点

服务能力已经扩展到了极限,再寻求扩展的话,就得从软件到硬件整体进行重构。

隔离性

隔离性实际上是可扩展性的基础,当我们将每个微服务都隔离为

独立的运行单元之后,任何一个或者多个微服务的失败都将只影

响自己或者少量其他微服务,而不会大面积地波及整个服务运行体系。

在架构设计上有一种实践模式,即隔板模式(Bulkhead Pattern),

这种架构设计模式的首要目的就是为了隔离系统中的各个功能

单元和实体,使得系统不会因为一个单元或者服务的失败而导致整体失败。

服务独立维护,分工明确

每个微服务都可以交由一个小团队进行开发,测试维护部

署,并对整个生命周期负责,当我们将每个微服务都隔离为

独立的运行单元之后,任何一个或者多个微服务的失败

都将只影响自己或者少量其他微服务,而不会大面积地波及整个服务。

当然,没有完美无瑕的技术,微服务也有自身的不足:

微服务应用是分布式系统,由此会带来固有的复杂性。开发者需要在RPC或者消息传递之间选择并完成进程间通讯机制。

他们必须写代码来处理消息传递中速度过慢或者不可用等

局部失效问题。当然这并不是什么难事,但相对于单体

式应用中通过语言层级的方法或者进程调用,微服务下这种技术显得更复杂一些。

简单介绍一下 springcloud

Spring Cloud 5大组件

服务发现——Netflix Eureka

客服端负载均衡——Netflix Ribbon

断路器——Netflix Hystrix

服务网关——Netflix Zuul

分布式配置——Spring Cloud Config

以以简单业务介绍springcloud的关系

单体项目

微服务项目

上一篇单体项目的docker部署已经写了,出现问题不会都可以问我

  http://mp.weixin.qq.com/s?__biz=MzA4MTAwMzA1Mw==&mid=2247484371&idx=1&sn=f320a2968d7b023c5356af32af354e6e&chksm=9f9ad491a8ed5d873e1d3f1573e0a332c9d46d1bfbade37be174e00e3c5f23e508eeaf76628a&token=1572617989&lang=zh_CN#rd

随便找一个项目进行部署

项目的地址

https://gitee.com/moxi159753/mogu_blog_v2/blob/Nacos/mogu_utils/pom.xml

简单的部署。我没有进行全面部署这个项目 教大家搭springcloud项目先搭主项目

记得加    <packaging>pom</packaging> <modules>        <module>mogu_utils</module>        <module>mogu_base</module>        <module>mogu_xo</module>        <module>mogu_admin</module>        <module>mogu_web</module>        <module>mogu_picture</module>        <module>mogu_sms</module>        <module>mogu_search</module>        <module>mogu_monitor</module>        <module>mogu_gateway</module>        <module>mogu_zipkin</module>        <module>mogu_spider</module>        <module>mogu_commons</module>    </modules>   <spring-cloud.version>2020.0.0-M6</spring-cloud.version>

   <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>        </dependencies>    </dependencyManagement>

子项目都是springboot项目 Eureka配置

  <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>        </dependency>springboot启动类@EnableEurekaServer配置ymleureka:  instance:    hostname: localhost  #EUReka服务端的名字  client:    register-with-eureka: false  #是不是向注册中心注册自己    fetch-registry: false # 自己这个是注册中心    service-url:     #监听页面      defaultZone: ${defaultZone:http://127.0.0.1:7002/eureka/}  # 访问这个进入 客服端http://localhost:7001/server:  port: ${post:7002}子eurekaeureka:  client:    service-url:      defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/  instance:    instance-id: http://localhost:8001启动类@EnableDiscoveryClient  // 服务发现@EnableEurekaClient  //服务发现 自动注册里面

客户端

RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。接下来我们就来看看这些操作方法的使用

@Configurationpublic class ConfigBean {    @Bean    @LoadBalanced    public RestTemplate getrestTemplate(){        return new RestTemplate();    }}@Controllerpublic class Restcccc {   @Autowired  private RestTemplate restTemplate;  @Autowired   private DiscoveryClient discoveryClient;@ResponseBody @RequestMapping("/bbbb") public String  fff(){//      String  url="http://localhost:8080/user";   //获取euraka 里面的实例     List<ServiceInstance> serviceregistration = discoveryClient.getInstances("serviceregistration");     ServiceInstance serviceInstance = serviceregistration.get(0);//获取注册索引为0 的服务   客户端可以看到  String url="http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user";   String forObject = restTemplate.getForObject(url, String.class);         http://localhost:8090/user<List><item><commodityid>1</commodityid><commodityname>衣服</commodityname><number>50</number><price>12.0</price></item><item><commodityid>2</commodityid><commodityname>不知道</commodityname><number>30</number><price>12.0</price></item></List>    return forObject; }}omponent@FeignClient(value = "SPRINGBOOT-PROVIDER-DEPYT",fallbackFactory = DeptclientServiceFallbackbanckfactory.class)public interface DeptClientService {    @PostMapping("/dept/add")    public boolean addDEpt(Dept dept);    @GetMapping("/dpty/{deptno}")    public Dept queryBy(long deptno);    @GetMapping("/LIST")    public List<Dept> queryAll();}获取请求

客服端负载均衡——Netflix Ribbon

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-ribbon</artifactId>    <version>1.4.7.RELEASE</version></dependency>启动类加入@EnableDiscoveryClient  // 服务发现@EnableEurekaClient  //服务发现 自动注册里面      //第一个参数  请求的地址  第2个参数   传递的参数   第3个参数   返回的类型    post请求           return restTemplate.postForObject(REST_URL_PREFTX+"/dept/add",dept,boolean.class);}}

有工具类的话(弄一个maven项目进行注入到springboot项目中)

hystrlx

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象被称为雪崩效应。<dependency>   <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>      <version>1.4.7.RELEASE</version></dependency>  Hystrix整个工作流如下:

构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数; 执行命令,Hystrix提供了4种执行命令的方法,后面详述; 判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动; 判断熔断器是否打开,如果打开,跳到第8步; 判断线程池/队列/信号量是否已满,已满则跳到第8步; 执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步; 统计熔断器监控指标; 走Fallback备用逻辑 返回请求响应启动类@EnableEurekaClient//添加对熔断的支持@EnableCircuitBreakerymlspring:        application:        name: springboot-provider-depyt        datasource:        type: com.alibaba.druid.pool.DruidDataSource        driver-class-name: com.mysql.cj.jdbc.Driver        username: root        password: 123456        url: jdbc:mysql://127.0.0.1:3306/datt?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8        mybatis:        mapper-locations: classpath:mapper/*.xmlserver:  port: 8001eureka:  client:    service-url:      defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/  instance:    instance-id: springboot-provider-depyt-hystix-8001    prefer-ip-address: true #可以显示服务的ip地址info:  app.name: zhudongdong1  company.name: kkkkkk1#开启服务降级feign:  hystrix:    enabled: true  @GetMapping("/dpty/{deptno}")   @HystrixCommand(fallbackMethod = "hydtrix_get") //出现问题进行熔断进入hydtrix_get()方法    public Dept GETdeptby(@PathVariable("deptno") long deptno){    Dept dept = deptService.queryBy((int) deptno);        if (dept==null){               throw new RuntimeException("这个id不存在 或信息找不到");      }      return dept;   }  @GetMapping("/LIST") public List<Dept>  GETHHH(){        return deptService.queryAll();         //  备选择方案  出现错误进行熔断      */    public Dept hydtrix_get(@PathVariable("deptno") long deptno){  

return new Dept().setDeptno(deptno).setDname("id=======>没有对应的信息,").setDb_source("熔断方法  意思就是出现错误就熔断");      } 

    //Feign服务降级@Componentpublic class DeptclientServiceFallbackbanckfactory implements FallbackFactory {    @Override    public Object create(Throwable throwable) {        return new DeptClientService() {            @Override            public boolean addDEpt(Dept dept) {                return false;            }

            @Override            public Dept queryBy(long deptno) {                return new Dept().setDb_source("降级 服务").setDname("11111111111");            }

            @Override            public List<Dept> queryAll() {                return null;            }        };    }}

服务网关——Netflix Zuul

  <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>            <version>1.4.7.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-zuul</artifactId>            <version>1.4.7.RELEASE</version>        </dependency>yml配置eureka:  client:    service-url:      defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/  instance:    instance-id: zuul1927    prefer-ip-address: trueinfo:  app.name: 监听你

zuul:  host:    connect-timeout-millis: 3000    socket-timeout-millis: 3000  routes:    mydept.serverid: springboot-provider-depyt    mydept.path: /mydeptcc/**ribbon:  ReadTimeout: 3000  ConnectTimeout: 3000hystrix:    command:      default:        execution:          isolation:            thread:              timeoutInMilliseconds: 60000@Componentpublic class LoginFilter extends ZuulFilter {    /*    网关过滤器     */    /*

     * filterType:返回字符串,代表过滤器的类型。包含以下4种:     * -- pre:请求在被路由之前执行     * -- route:在路由请求时调用     * -- post:在route和errror过滤器之后调用     * -- error:处理请求时发生错误调用     * @return 返回以上四个类型的名称     */

    @Override    public String filterType() {        return "pre";    }    /**     * filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。     * @return     */

    @Override    public int filterOrder() {        return 10;    }    /**     * shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。     * @return     */

    @Override    public boolean shouldFilter() {        return true;    }    /**     * run:编写过滤器的具体业务逻辑。     * @return     * @throws ZuulException     */

    @SneakyThrows    @Override    public Object run() throws ZuulException {        System.out.println("执行");        //获取zuul提供的上下文对象        RequestContext context = RequestContext.getCurrentContext();        //获取request对象        HttpServletRequest request = context.getRequest();        HttpServletResponse response = context.getResponse();        System.out.println(request);        String deptno = request.getParameter("deptno");        System.out.println(deptno);        Integer d=Integer.parseInt(deptno);        if (d==1){

            System.out.println("============>我是网关过滤器<============");            //过滤该请求,不对其进行路由            context.setSendZuulResponse(false);            //设置响应码401            context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);            //设置响应体            response.setContentType("text/html;charset=UTF-8");            PrintWriter writer = response.getWriter();            writer.println("以前可以访问  现在老子给过滤了 就是不要你访问 打我");

//            /*    context.setResponseBody("以前可以访问  现在老子给过滤了 就是不要你访问 打我");            执行org.springframework.cloud.netflix.zuul.filters.pre.Servlet30RequestWrapper@5df6e8ef1============>我是网关过滤器<============页面输出 以前可以访问 现在老子给过滤了 就是不要你访问 打我             */        }        return null;    }}启动类@EnableZuulProxy@EnableEurekaClient

分布式配置——Spring Cloud Config

配置spring.cloud.config.server.git.uri=https://gitee.com/zhu_dongdong/springcloud-config.git#2021-01-18 19:05:48.903  INFO 4432 --- [nio-8080-exec-8] o.s.c.c.s.e.NativeEnvironmentRepository  : Adding property source: file:/C:/Users/lenovo/AppData/Local/Temp/config-repo-2610732798174323820/config-server.ymserver.port=3344spring.application.name=config-demoeureka:  client:    service-url:      defaultZone: http://localhost:7001/eureka/ 启动类@EnableConfigServer //客户端@EnableEurekaClien     

总结

Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务

部署 配置docker

 <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>            <!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin -->            <plugin>                <groupId>com.spotify</groupId>                <artifactId>docker-maven-plugin</artifactId>                <version>0.4.13</version>                <configuration>                    <!-- 注意imageName一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 -->                    <!-- 详见:https://github.com/spotify/docker-maven-plugin    Invalid repository name ... only [a-z0-9-_.] are allowed-->                    <imageName>article</imageName>                    <baseImage>jdk1.8</baseImage>                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>                    <resources>                        <resource>                            <targetPath>/</targetPath>                            <directory>${project.build.directory}</directory>                            <include>${project.build.finalName}.jar</include>                        </resource>                    </resources>                    <dockerHost>http://192.168.66.138:2375</dockerHost>                </configuration>            </plugin>        </plugins>

第2中

<!--spring boot打包的话需要指定一个唯一的入门-->    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>                <configuration>                    <!-- 指定该Main Class为全局的唯一入口 -->                    <mainClass>com.moxi.mogublog.admin.AdminApplication</mainClass>                    <layout>ZIP</layout>                </configuration>                <executions>                    <execution>                        <goals>                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->                        </goals>                    </execution>                </executions>            </plugin>            <!--docker镜像build插件-->            <plugin>                <groupId>com.spotify</groupId>                <artifactId>docker-maven-plugin</artifactId>                <version>1.2.0</version>                <configuration>                    <!-- 注意imageName一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 -->                    <imageName>registry.cn-shenzhen.aliyuncs.com/mogublog/${project.artifactId}</imageName>                    <dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory>                    <rm>true</rm>                    <resources>                        <resource>                            <targetPath>/</targetPath>                            <directory>${project.build.directory}</directory>                            <include>${project.build.finalName}.jar</include>                        </resource>                    </resources>                </configuration>            </plugin>        </plugins>    </build>

进行配置先去编写dockerfile

FROM java:alpineVOLUME /tmpADD mogu_admin-0.0.1-SNAPSHOT.jar app.jarENTRYPOINT ["java","-Xms256m","-Xmx256m","-jar","/app.jar"]

前端的话

FROM registry.cn-shenzhen.aliyuncs.com/mogublog/nginx:latestADD ./dist/ /usr/share/nginx/htmlRUN sed -i 's/\r$//' /usr/share/nginx/html/env.shRUN chmod +x /usr/share/nginx/html/env.shENTRYPOINT ["/usr/share/nginx/html/env.sh"]CMD ["nginx", "-g", "daemon off;"]自动生成nginx镜像 没有配置端口但是启动了

先去idea插件去安装docker

在run进行配置 docker没有2379可以去百度开启 博客

https://blog.csdn.net/qq_28796037/article/details/115002327?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.control&spm=1001.2101.3001.4242

后端 前端 记得root的maven进行install进行整体打包(全打成jar包) 启动jar的话 进行点击启动进行生成镜像 点击docker ps 启动的话记得连接docker的mysql

docker 挂载的mysql启动

docker run --name mysql -d -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.7.27

密码root

账号root

不加--name

docker run -d -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.7.27

redis

docker run -d -p 6378:6379 --name port-redis redis

docker run -p 6379:6379 --name redis -v /root/redis/redis.conf:/etc/redis/redis.conf  -v /root/redis/data:/data -d redis:latest redis-server /etc/redis/redis.conf --appendonly yes-p 6379:6379:把容器内的6379端口映射到宿主机6379端口-v /root/redis/redis.conf:/etc/redis/redis.conf:把宿主机配置好的redis.conf放到容器内的这个位置中-v /root/redis/data:/data:把redis持久化的数据在宿主机内显示,做数据备份redis-server /etc/redis/redis.conf:这个是关键配置,让redis不是无配置启动,而是按照这个redis.conf的配置启动–appendonly yes:redis启动后数据持久化

nginx

 docker run --name nginx-test -p 8080:80 -d nginx

启动jar和前端

启动是容器要想删除 停止在删除sudo  docker run -p 7001:7001 客户端的名字(镜像名字):0.01docker run -p 本机映射端口:镜像映射端口 -d --name 启动镜像名称 -e 镜像启动参数  镜像名称:镜像版本号参数释义:

     -p   本机端口和容器启动端口映射      -d   后台运行     --name   容器名称     -e    镜像启动参数 去一个一个启动jardocker  images  出来都是镜像
docker  images  出来都是镜像出现的问题 删除镜像删除镜像docker image rm 镜像名称/镜像ID删除容器sudo  docker rm 18e2afef12b5docker  stop 容器id  停止容器

最后的方法就是在nginx配置2个前端 一个前台一个后台(配置2个nginx端口,可以配置2个html地址 改变访问路径就可以了)

server {    listen       80;    server_name  localhost;    #charset koi8-r;    #access_log  /var/log/nginx/host.access.log  main;    #第一种方法  这个直接/访问

    location / {        root   /usr/share/nginx/html;        index  index.html index.htm;    }    #根/student 访问 指向地点

    location /student {        alias   /usr/share/nginx/student;        index  index.html index.htm;        }    #error_page  404              /404.html;    # redirect server error pages to the static page /50x.html    #    error_page   500 502 503 504  /50x.html;    location = /50x.html {        root   /usr/share/nginx/html;    }    # proxy the PHP scripts to Apache listening on 127.0.0.1:80    #    #location ~ \.php$ {    #    proxy_pass   http://127.0.0.1;    #}    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000    #    #location ~ \.php$ {    #    root           html;    #    fastcgi_pass   127.0.0.1:9000;    #    fastcgi_index  index.php;    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;    #    include        fastcgi_params;    #}    # deny access to .htaccess files, if Apache's document root    # concurs with nginx's one    #    #location ~ /\.ht {    #    deny  all;    #}}

docker的nginx挂载 宿机路径:容器的内的路径 模板

sudo docker run -d -p 3310:3306 -v /home/qq3175449063/conf:/etc/mysql/conf.d -v/home/qq3175449063/data:/var/lib/mysql -e MYSQL_ROOR_PASSWORD=123456 --name mysql01 daocloud.io/library/mysql:5.7

docker run --name mynginx2 -p 2222:80 -v /data/nginx/html:/usr/share/nginx/html -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf  -v /data/nginx/logs:/var/log/nginx -v /data/nginx/conf.d:/etc/nginx/conf.d -d --restart=always nginx:latest其中-v 就表示挂载目录,也就是说当容器中的nginx配置的访问路径是/usr/share/nginx/html时,实际上访问的是linux中的/data/nginx/html。

进入nginx容器  容器的id通过docker exec命令进入容器:docker exec -it d554669f2616 /bin/bashexit退出记得

遇到的问题

但在 nginx 配置中,如果没有配置任何一个 443 的 https 服务的话,默认服务器是不响应 443 接口的,但是如果一旦配置了一个 443 服务,那么所有的 443 接口都会默认使用这个配置(源于 nginx 的服务搜索策略),所以一旦在私有仓库的 nginx 上配置了其它 443 服务,就需要屏蔽一下仓库域名下 443 接口返回的内容。

解决方案:配置 nginx 的 default_server,默认不进行返回,另外注意默认的 443 虽然不需要返回内容,但仍然需要配置 ssl 证书,否则 nginx 会报错,证书随意。通过 return 444 来中止响应。

复制代码server {     listen 443 default_server;     server_name _ ;     ssl on;     ssl_certificate             随便设置一个ssl证书;                     ssl_certificate_key     随便设置一个ssl证书的key;     return 444;}

昨天说挂载后端的项目,现在说挂载前端的2个vue项目,这里先安装2个nginx进行挂载

进行配置挂载的nginx




已经将2个vue的项目拉进去了 进行挂载 2个挂载的nginx.conf是一样的

worker_processes  1;events {    worker_connections  1024;}http {    include       mime.types;    default_type  application/octet-stream;    sendfile        on;    keepalive_timeout  65;    server {        listen       80;        server_name  localhost;        location / {            root   /usr/share/nginx/html;        try_files $uri $uri/ /index.html last; # 别忘了这个哈            index  index.html index.htm;        }        error_page   500 502 503 504  /50x.html;        location = /50x.html {            root   html;        }    }}

进行run

docker run --name ngin -d -p 8080:80  -v /home/qq3175449063/nginx1/html:/usr/share/nginx/html -v /home/qq3175449063/nginx1/nginx.conf:/etc/nginx/nginx.conf  -d nginxdocker run --name nginx1  -d  -p 8000:80 -d   registry.cn-shenzhen.aliyuncs.com/mogublog/nginxdocker run --name nginx6 -d -p 8000:80  -v /home/qq3175449063/nginx2/html:/usr/share/nginx/html -v /home/qq3175449063/nginx2/nginx.conf:/etc/nginx/nginx.conf  -d registry.cn-shenzhen.aliyuncs.com/mogublog/nginx

看结果

一个端口号是8000 一个端口号是8080 昨天前端不是写了dockerfile

我们启动看看sudo  docker run -p 9528:9528    registry.cn-shenzhen.aliyuncs.com/mogublog/vue_mogu_admin

这里少写1个脚本 看

FROM registry.cn-shenzhen.aliyuncs.com/mogublog/nginx:latestADD ./dist/ /usr/share/nginx/htmlRUN sed -i 's/\r$//' /usr/share/nginx/html/env.shRUN chmod +x /usr/share/nginx/html/env.shENTRYPOINT ["/usr/share/nginx/html/env.sh"]CMD ["nginx", "-g", "daemon off;"]

脚本(移除启动容器时出现的日志显示)

#!/bin/bash# set -xset -e

# Recreate config fileabsolute_path=$(cd `dirname $0`; pwd)env_config=${absolute_path}/env-config.js

rm -rf ${env_config}touch ${env_config}

# Add assignmentecho "window._env_ = {" >> ${env_config}

# Read each line in .env file# Each line represents key=value pairs

sed -i '/^[[:space:]]*$/d' ${absolute_path}/.envwhile read -r line || [[ -n "$line" ]];do  # Split env variables by character `=`  if printf '%s\n' "$line" | grep -q -e '='; then    varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')    varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')  fi

  # Read value of current variable if exists as Environment variable  value=$(printf '%s\n' "${!varname}")  # Otherwise use value from .env file  [[ -z $value ]] && value=${varvalue}

  # Append configuration property to JS file  echo "  $varname: \"$value\"," >> ${env_config}done < ${absolute_path}/.envsed -i '/^[[:space:]]*$/d' ${absolute_path}/.default.envwhile read -r line || [[ -n "$line" ]];do  # Split env variables by character `=`  if printf '%s\n' "$line" | grep -q -e '='; then    varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')    varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')  fi

  # Read value of current variable if exists as Environment variable  value=$(printf '%s\n' "${!varname}")  # Otherwise use value from .env file  [[ -z $value ]] && value=${varvalue}

  # Append configuration property to JS file  echo "  $varname: \"$value\"," >> ${env_config}done < ${absolute_path}/.default.env

echo "}" >> ${env_config}sed -e "s/\//\\\/g" ${env_config}STR=`echo $(cat ${env_config}) | sed 's#\/#\\\/#g'`mv ${absolute_path}/index.html ${absolute_path}/index.html.bak#sed -e "s/window\.\_env\_.*\}\;/${STR}/g" ${absolute_path}/index.html.bak > ${absolute_path}/index.htmlsed -e "s#<script id=env>window._env_.*\};</script>#<script id=env>${STR};</script>#g" ${absolute_path}/index.html.bak > ${absolute_path}/index.htmlcat ${env_config}

exec "$@"

我们需要准备两个配置文件 config/vue_mogu_web.env 和 config/vue_mogu_admin.env ,这两个配置文件将在下面Docker compose 脚本中使用到 vue_mogu_web.env

NODE_ENV=productionVUE_MOGU_WEB=http://192.168.1.101:9527PICTURE_API=http://192.168.1.101:8602WEB_API=http://192.168.1.101:8603ELASTICSEARCH=http://192.168.1.101:8605

vue_mogu_admin.env

WEB_API=http://192.168.1.101:8603FILE_API=http://192.168.1.101:8600/RABBIT_MQ_ADMIN=http://192.168.1.101:15672SENTINEL_ADMIN=http://192.168.1.101:8070/sentinel/EUREKA_API=http://192.168.1.101:8761Search_API=http://192.168.1.101:8605ADMIN_API=http://192.168.1.101:8601Zipkin_Admin=http://192.168.1.101:9411/zipkin/DRUID_ADMIN=http://192.168.1.101:8601/druid/login.htmlSPRING_BOOT_ADMIN=http://192.168.1.101:8606/wallboardBLOG_WEB_URL=http://192.168.1.101:9527ELASTIC_SEARCH=http://192.168.1.101:5601PICTURE_API=http://192.168.1.101:8602SOLR_API=http://192.168.1.101:8080/solr

vue_mogu_admin.yml

version: '3'services:  #授权服务  vue_mogu_admin:    image: registry.cn-shenzhen.aliyuncs.com/mogublog/vue_mogu_admin:latest    container_name: vue_mogu_admin    restart: always    ports:      - 9528:80    networks:      - mogu    env_file:      - ../config/vue_mogu_admin.env    environment:      - COMPOSE_PROJECT_NAME=vue_mogu_admin

networks:  mogu:    external: true

vue_mogu_web.yml 的内容如下

version: '3'services:  #授权服务  vue_mogu_admin:    image: registry.cn-shenzhen.aliyuncs.com/mogublog/vue_mogu_admin:latest    container_name: vue_mogu_admin    restart: always    ports:      - 9528:80    networks:      - mogu    env_file:      - ../config/vue_mogu_admin.env    environment:      - COMPOSE_PROJECT_NAME=vue_mogu_admin

networks:  mogu:    external: true

vue_mogu_web.yml 的内容如下

version: '3'services:  #授权服务  vue_mogu_web:    image: registry.cn-shenzhen.aliyuncs.com/mogublog/vue_mogu_web:latest    container_name: vue_mogu_web    restart: always    ports:      - 9527:80    networks:      - mogu    env_file:      - ../config/vue_mogu_web.env    environment:      - COMPOSE_PROJECT_NAME=vue_mogu_webnetworks:  mogu:    external: true

vue_run.sh

#!/usr/bin/env bash

echo '=====开始运行前台====='

cd docker-compose

echo '=====开始运行mogu_gateway====='

docker-compose -f vue_mogu_admin.yml up -d

echo '=====开始运行mogu_admin====='

docker-compose -f vue_mogu_web.yml up -d

然后开始运行前端的脚本

sh vue_run.sh 其实,制作的镜像里面就包含nginx,然后暴露80端口,映射到我们前端项目上 其实docker的 compose 都是脚本 所有我建议还是使用2个nginx进行部署微服务的前端项目

docker-compose.yml 属性

version:指定 docker-compose.yml 文件的写法格式services:多个容器集合build:配置构建时,Compose 会利用它自动构建镜像,该值可以是一个路径,也可以是一个对象,用于指定 Dockerfile 参数build: ./dir---------------build:    context: ./dir    dockerfile: Dockerfile    args:        buildno: 1command:覆盖容器启动后默认执行的命令command: bundle exec thin -p 3000----------------------------------command: [bundle,exec,thin,-p,3000]dns:配置 dns 服务器,可以是一个值或列表dns: 8.8.8.8------------dns:    - 8.8.8.8    - 9.9.9.9dns_search:配置 DNS 搜索域,可以是一个值或列表dns_search: example.com------------------------dns_search:    - dc1.example.com    - dc2.example.comenvironment:环境变量配置,可以用数组或字典两种方式environment:    RACK_ENV: development    SHOW: 'ture'-------------------------environment:    - RACK_ENV=development    - SHOW=tureenv_file:从文件中获取环境变量,可以指定一个文件路径或路径列表,其优先级低于 environment 指定的环境变量env_file: .env---------------env_file:    - ./common.envexpose:暴露端口,只将端口暴露给连接的服务,而不暴露给主机expose:    - "3000"    - "8000"image:指定服务所使用的镜像image: javanetwork_mode:设置网络模式network_mode: "bridge"network_mode: "host"network_mode: "none"network_mode: "service:[service name]"network_mode: "container:[container name/id]"ports:对外暴露的端口定义,和 expose 对应ports:   # 暴露端口信息  - "宿主机端口:容器暴露端口"- "8763:8763"- "8763:8763"links:将指定容器连接到当前连接,可以设置别名,避免ip方式导致的容器重启动态改变的无法连接情况links:    # 指定服务名称:别名     - docker-compose-eureka-server:compose-eurekavolumes:卷挂载路径volumes:  - /lib  - /varlogs:日志输出信息

--no-color          单色输出,不显示其他颜.-f, --follow        跟踪日志输出,就是可以实时查看日志-t, --timestamps    显示时间戳--tail              从日志的结尾显示,--tail=200

docker部署微服务项目相关推荐

  1. Docker 部署微服务项目

    目录 一.前言 二.环境准备 1.安装 Docker 2.Docker 安装 MySQL 3.Docker 安装 Redis 4.Docker 安装 Nacos 5.Docker 安装 Nginx 三 ...

  2. Java学习 --- docker部署微服务项目

    目录​​​​​​​ 一.创建一个springboot项目 1.1.修改pom.xml文件 1.2.修改application.properties配置文件 1.3.创建controller层和类 1. ...

  3. k8s部署微服务项目

    之前用docker-compose部署微服务项目,但是只能单节点的(那你用微服务架构干啥?),所以想搞一下k8s集群,网上找了下资料没有视频专门讲这一块,自己找了很多资料,搞了蛮长时间的,所以记录一下 ...

  4. IDEA集成Docker插件实现一键自动打包部署微服务项目

    一. 前言 大家在自己玩微服务项目的时候,动辄十几个服务,每次修改逐一部署繁琐不说也会浪费越来越多时间,所以本篇整理通过一次性配置实现一键部署微服务,实现真正所谓的一劳永逸. 二. 配置服务器 1. ...

  5. k8s+jenkins+docker部署微服务实现CI/CD

    "所爱隔山海,山海不可平,海有舟可渡,山有路可行,此爱翻山海,山海皆可平." 作为一个想搞开发的,最近似乎都在干运维,不知道有没有跑偏... 2021.5.14 一般的中小公司个人 ...

  6. Docker部署微服务应用笔记(三)

    Docker安装java:8环境 因为现在都是使用java8开发直接使用命令: docker pull java这是默认下载最新版本镜像 docker pull java:8这是下载指定版本镜像 列出 ...

  7. Docker部署微服务详解

    2019独角兽企业重金招聘Python工程师标准>>> 2013年发布至今,Docker一直广受瞩目,被认为可能会改变软件行业. 但是,许多人并不清楚Docker 到底是什么,要解决 ...

  8. pg安装部署linux_简简单单基于docker部署微服务网关

    ❝ 本文整理于今年3月,收录在个人开源仓库JavaScriptCollection中,其中很多概念不乏借鉴.摘抄自官网,便于复习相关概念,有兴趣的可以直接去仓库Clone文档学习.参考! ❞ 基本概念 ...

  9. jenkins部署微服务项目

    新手上路,对着视频做了一个谷粒的在线教育项目.测试跑通之后,想要自己试着部署到自己的云服务器上,闲着也是闲着不是.言归正传 简介 在微服务架构中,随着服务越来越多,服务的打包部署就会成为一个相当麻烦的 ...

最新文章

  1. 从硬件到框架,30+巨头参与的AI基准竞争结果公布(第一回合)
  2. mysql使用bka_MySQL Batched Key Access (BKA)原理和设置使用方法举例
  3. python中的系统模块_python中一些获取系统信息的模块
  4. Oracle代码大全.从入门到熟练
  5. 【翻译】eXpressAppFramework QuickStart 业务模型设计(十)——在代码中实现数据验证...
  6. 如何在SharePoint 2010项目中引用UserProfiles.dll
  7. 用例子理解java7内存结构
  8. 编程语言对比 容器
  9. 往事如烟,残阳如血......——逝去的背影(五)
  10. CISP 考试教材《第 2 章 知识域:网络安全监管》知识整理
  11. java contains 效率_List与Set的contains方法效率问题
  12. SylixOS学习二—— SylixOS认识和使用_SylixOS虚拟机使用
  13. 使用NAudio音频文件剪切指定片段
  14. 056.单链表就地逆置
  15. Android学习笔记——活动,从创建到销毁
  16. 机械结构day_13
  17. 人工智能 之 定义与发展
  18. 云服务器备案和网站备案区别,服务器备案和不备案有什么区别吗?
  19. halcon中如何生成椭圆_教你动态生成椭圆,还教你怎么用海龟作图——GeoGebra制作教程...
  20. 易语言web服务器e2ee_用各种方法搭建自己的个人网页服务器

热门文章

  1. Day04 关键字、标识符、变量及运算符
  2. 【Verilog数字系统设计(夏雨闻)6-------模块的结构、数据类型、变量和基本运算符号2】
  3. Android 学习记录(持续更新)
  4. 一次Wi-Fi入侵实录
  5. Java进阶(四)多态
  6. 【区块链108将】微数链林道坤:区块链有助于更好的发挥大数据价值
  7. 音频变速播放原理分析及实现方案
  8. 完爆90%的性能毛病,收好数据库优化八大通用绝招
  9. 数据处理 | MATLAB实现KNN(K近邻)缺失数据填补
  10. SSH免密登录(笔记)