#压缩成bz2文件,demo.txt.bz2 bzip2 demo.txt #解压缩bz2文件,demo.txt bunzip2 demo.txt.bz2 #压缩成gz文件,demo.txt.gz gzip demo.txt #解压缩bz2文件,demo.txt gunzip demo.txt.gz #压缩成rar文件,package(首先要安装rar命令才行) rar a package #解压缩bz2文件,package.rar rar x package #把package文件压缩到demo.bz2里面 tar -jcvf demo.bz2 package #查看demo.tar文件 tar -tf demo.bz2 #解压demo.bz2文件 tar -jxvf demo.bz2 #把package文件压缩到demo.tar.gz里面 tar -zcvf demo.tar.bz2 package #解压demo.tar.gz文件 tar -zxvf demo.tar.gz #删除文件 rm -f demo.txt #删除文件夹 rmdir package
import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class ThreadPoolAllDoneCheck { public static void main(String[] args) { // 创建固定大小线程池 ExecutorService executor = Executors.newFixedThreadPool(5); // 存放 Future 结果 List<Future<Boolean>> futures = new ArrayList<>(); try { // 提交多个任务 for (int i = 0; i < 10; i++) { futures.add(executor.submit(() -> yourTask())); } // 等所有线程执行完成后，再统一判断结果 boolean hasFalse = false; for (Future<Boolean> future : futures) { try { Boolean result = future.get(); // 阻塞直到任务完成 if (!result) { hasFalse = true; } } catch (ExecutionException e) { // 捕获任务内部抛出的异常 e.printStackTrace(); hasFalse = true; // 认为失败 } } // 所有线程都完成后再判断 if (hasFalse) { throw new RuntimeException("存在任务执行结果为 false！"); } System.out.println("全部任务执行成功！"); } catch (InterruptedException e) { e.printStackTrace(); } finally { executor.shutdown(); } } // 模拟你的业务方法 public static boolean yourTask() throws InterruptedException { Thread.sleep(500); // 模拟耗时 boolean result = Math.random() > 0.2; // 80% 概率返回 true System.out.println(Thread.currentThread().getName() + " 执行任务，结果: " + result); return result; } }
在实体类里定义一个数据库不存在的字段
1、在mybatis中定义不存在字段//引入 import org.springframework.data.annotation.Transient; //使用 @Transient private List<AwardGuidelineFile> awardGuidelineFileList;2、在jpa项目中定义不存在字段//引入包 import javax.persistence.Transient; //使用 @Transient protected FsCatalog bsParent;3、在mybatis-plus中定义不存在字段@TableField（exist = "false"） private String name;
1、jvm 内存模型程序计数器 Program Counter Register：记录的是正在执行的虚拟机字节码指令的地址。此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError的区域虚拟机：VM Stack描述的是 JAVA 方法执行的内存模型，每个方法在执行的时候都会创建一个栈帧， 用于存储局部变量表，操作数栈，动态链接，方法接口等信息局部变量表存储了编译期可知的各种基本数据类型、对象引用线程请求的栈深度不够会报 StackOverflowError 异常栈动态扩展的容量不够会报 OutOfMemoryError 异常虚拟机栈是线程隔离的，即每个线程都有自己独立的虚拟机栈本地方法：Native Stack本地方法栈类似于虚拟机栈，只不过本地方法栈使用的是本地方法堆：Heap几乎所有的对象实例都在堆上分配内存2、堆所有的对象实例以及数组都要在堆上分配。堆是垃圾收集器管理的主要区域，也被称为“GC 堆”；也是我们优化最多考虑的地方。 堆可以细分为：1.新生代Eden 空间From Survivor 空间To Survivor 空间2.老年代3.永久代/元空间Java8 以前永久代，受 jvm 管理，java8 以后元空间，直接使用物理内存。因此， 默认情况下，元空间的大小仅受本地内存限制。 垃圾回收从 Java8 开始，HotSpot 已经完全将永久代（Permanent Generation）移除，取而代之的是一 个新的区域—元空间（MetaSpace）3、运行图由于FGC的速度比YGC的速度慢得多，所以JVM的优化也是尽量避免FGC
1.Docker安装Nginx并启动#没有安装的情况下会自动安装，可以指定版本 docker run -p 80:80 --name nginx -d nginx:1.10 #将容器内的配置文件拷贝到当前目录 #别忘了后面的点 docker container cp nginx:/etc/nginx . #修改文件名称并把这个 conf 移动到/mydata/nginx 下 mv nginx conf #终止原容器 docker stop nginx #执行命令删除原容器 docker rm nginx #创建新的 nginx；执行以下命令 docker run -p 80:80 --name nginx \ -v /mydata/nginx/html:/usr/share/nginx/html \ -v /mydata/nginx/logs:/var/log/nginx \ -v /mydata/nginx/conf:/etc/nginx \ -d nginx:1.10 #给 nginx 的 html 下面放的所有资源可以直接访问 drwxr-xr-x. 3 root root 34 Oct 17 07:49 html2.搭建域名访问要求是 ： 访问gulimall.com 能访问到我们自己本机idea中启动的product服务思路：我们通过配置本地的host域名映射我们虚拟机的中的nginx，然后nginx在根据转发规把请求转发回我们自己的idea中的本地服务。前置说明：因为我们的nginx的安装在云服务器上的，本地Host文件解析域名后访问云服务器, 结果请求被拦截虽然可以用谷歌浏览器安装ModHeader插件解决，但是我们在把请求映射到nginx后，在让nginx转发回我们本地的服务是无法完成的，因为云服务器无法ping通我们本地的ip 原因 本地pc属于移动宽带的内网环境，说白了就是cmd下ipconfig里的ip是你电脑宽带运营商的一个大网络（外网）下的一个内网ip，服务器无法主动与内网ip建立连接，连路由都做不到。所以不可能ping通的。可以考虑使用VPN在您的电脑和服务器之间建立VPN连接，这样服务器和您的电脑就能像在同一个内网一样互相访问了2.1配置本地host可以利用SwitchHost配置工具。需要注意的是这个软件要用管理员打开，然后C:\Windows\System32\drivers\etc把hosts的文件权限放开，才能进行修改如下图配置，前面是虚拟机的地址，后面是需要解析的域名2.2配置nginx# 查看我们nginx的总配置文件 [root@ecs-284198 conf]# cat /mydata/nginx/conf/nginx.conf user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; } [root@ecs-284198 conf]# # 当前总文件的最后一行 include /etc/nginx/conf.d/*.conf; 他会加载这个路径下的所有以 .conf结尾的文件作为配置文件，并且在包含到我们的当前的总配置文件中，这样就不会导致一个配置文件很大，所以接下来我们到 conf.d 的目录下新建一个gulimall.conf文件 # cd 到 /mydata/nginx/conf/conf.d/会有一个default.conf，然后我们复制一个default.conf为gulimall.conf [root@ecs-284198 conf.d]# cd /mydata/nginx/conf/conf.d/ [root@ecs-284198 conf.d]# ll total 8 -rw-r--r-- 1 root root 1097 Jan 31 2017 default.conf -rw-r--r-- 1 root root 1065 Apr 28 21:56 gulimall.conf [root@ecs-284198 conf.d]# # 修改后的gulimall.conf 如下 server { listen 80; server_name gulimall.com; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { proxy_pass http://192.168.56.1:15000; } #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; #} } # 其中 proxy_pass http://192.168.56.1:15000; 中的IP使我们本地的ip,访问会我们自己本地idea启动的product服务 # 但是这样会有一个问题 如果我们的product服务有多个实列，就不好办了，其实这个proxy_pass http://192.168.56.1:15000应该配置成我们的网卡 gateway， 让gateway负载均衡到我们的服务中去，下一节我们会解决这个问题3.Nginx-搭建域名访问（负载就均衡到网关）3.1修改总nginx的配置文件# 在http 模块中配置 upstream [root@ecs-284198 conf]# cat nginx.conf user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; + upstream gulimall{ + server 192.168.56.1:88; + } include /etc/nginx/conf.d/*.conf; } # 配置文件中upstream 叫上有服务器 然后取了一个名字叫gulimall，然后里面的里面配置的是我们网关的地址，就是以后所有请求我们上游服务器gulimall 的地址都会转发到网关去3.2修改gulimall.conf# 在子配置文件gulimall.conf中，的location 块添加 proxy_set_header Host $host; 表示nginx在转发的时候把host也带上，如果不加，nginx会丢失请求头，host，cookies等信息 把原来请求我们product的服务改成proxy_pass http://gulimall;其中 http://gulimall中的gulimall 就是我们在总配置文件中取的上游服务器的名字， # 整配置文件的意思，就是监听到gulimall域名发送过来的80请求，都会转到上游服务器为gulimall中去，并且带上host信息，而上游服务器又是转发到网关的。 [root@ecs-284198 conf]# cat conf.d/gulimall.conf server { listen 80; server_name gulimall.com; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { + proxy_set_header Host $host; + proxy_pass http://gulimall; } #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; #} }3.3修改gateway服务的yaml配置spring: cloud: gateway: routes: # - id: test_route # uri: https://www.baidu.com # predicates: # - Query=url,baidu # # - id: qq_route # uri: https://www.qq.com # predicates: # - Query=url,qq - id: product_route uri: lb://gulimall-product predicates: - Path=/api/product/**,/hello filters: - RewritePath=/api/(?<segment>.*),/$\{segment} - id: third_party_route uri: lb://gulimall-third-party predicates: - Path=/api/thirdparty/** filters: - RewritePath=/api/thirdparty/(?<segment>.*),/$\{segment} - id: member_route uri: lb://gulimall-member predicates: - Path=/api/member/** filters: - RewritePath=/api/(?<segment>.*),/$\{segment} - id: ware_route uri: lb://gulimall-ware predicates: - Path=/api/ware/** filters: - RewritePath=/api/(?<segment>.*),/$\{segment} - id: admin_route uri: lb://renren-fast predicates: - Path=/api/** filters: - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment} # 注意要放最后 - id: gulimall_host_route uri: lb://gulimall-product predicates: - Host=gulimall.com4.简单认识一下Nginx和工作原理5.性能压测-优化-Nginx动静分离由于动态资源和静态资源目前都处于服务端，所以为了减轻服务器压力，我们将js、css、img等静态资源放置在Nginx端，以减轻服务器压力。5.1动静态文件上传到 mydata/nginx/html/static/index/css，这种格式5.2修改index.html的静态资源路径修改index.html的静态资源路径，加上static前缀src=“/static/index/img/img_09.png”5.3修改/mydata/nginx/conf/conf.d/gulimall.conf如果遇到有/static为前缀的请求，转发至html文件夹location /static/ { root /usr/share/nginx/html; } location / { proxy_pass http://gulimall; proxy_set_header Host $host; }
1.引入jar包 org.springframework.boot spring-boot-starter-thymeleaf 2.后端代码package com.atguigu.gulimall.product.web; import com.atguigu.gulimall.product.entity.CategoryEntity; import com.atguigu.gulimall.product.service.CategoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; import java.util.Map; @Controller public class IndexController { @Autowired CategoryService categoryService; @GetMapping({"/", "/index.html"}) public String indexPage(Model model) { //1.查出所有的一级分类 List<CategoryEntity> categoryEntities = categoryService.getLevel1Categorys(); model.addAttribute("categorys", categoryEntities); //视图解析器进行拼串 //"classpath:/templates/" +返回值+ ".html" return "index"; } }3.在resource下新建templates文件夹（页面都放进这里面） 谷粒商城2020 X 家用电器 Hi, 欢迎来到! 登录 注册 新人福利 PLUS会员 促销 公告 更多 全民纸巾大作战 家具建材满999减300元 黑科技冰箱，下单立减千元 抢102减101神券！ 关于召回普利司通（天津）轮胎有限公司2个规格乘用车轮胎的公告 物流推出配送员统一外呼电话"95056” 天府大件运营中心开仓公告 大件物流“送装一体”服务全面升级！ 话费 机票 酒店 游戏 企业购 加油卡 电影票 火车票 众筹 理财 礼品卡 白条 话费 机票 酒店 游戏 X 话费充值 流量充值 套餐变更 号码 面值 100元 20元 50元 10元 2元 ￥98.0-￥100.0 快速充值 抢99减50元话费 X 国际机票 国际/港澳 特惠活动 单程 往返 机票查询 当季热门特惠机票 X 国内港澳台 促销活动 酒店查询 订酒店到 X 点卡 QQ 页游 面值 面值 面值 面值 ￥0.00 直充 卡密 快速充值 吃鸡就要快人一步 4.简单语法示例，更多语法参考官网https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html Welcome to our grocery store! 5.修改Thymeleaf的文件后能及时在页面更新，则要关闭缓存spring: thymeleaf: cache: false6.如果resource下的static文件读取不到时，可以加入以下配置或者在pom文件中加入spring: mvc: static-path-pattern: /static/**或者在pom文件中加入以下配置 false src/main/resources **/*.properties **/*.xml **/*.yml static/**
1.给es中建立索引。product,建立好映射关系PUT product { "mappings": { "properties": { "skuId": { "type": "long" }, "spuId": { "type": "long" }, "skuTitle": { "type": "text", "analyzer": "ik_smart" }, "skuPrice": { "type": "keyword" }, "skuImg": { "type": "keyword", "index": false, "doc_values": false }, "saleCount": { "type": "long" }, "hosStock": { "type": "boolean" }, "hotScore": { "type": "long" }, "brandId": { "type": "long" }, "catelogId": { "type": "long" }, "brandName": { "type": "keyword", "index": false, "doc_values": false }, "brandImg": { "type": "keyword", "index": false, "doc_values": false }, "catelogName": { "type": "keyword", "index": false, "doc_values": false }, "attrs": { "type": "nested", "properties": { "attrId": { "type": "long" }, "attrName": { "type": "keyword", "index": false, "doc_values": false }, "attrValue": { "type": "keyword" } } } } } }2.Service类package com.atguigu.gulimall.lsearch.service; import com.atguigu.common.to.es.SkuEsModel; import java.io.IOException; import java.util.List; public interface ProductSaveService { boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException; }3.ServiceImpl类package com.atguigu.gulimall.lsearch.service.iml; import com.alibaba.fastjson.JSON; import com.atguigu.common.to.es.SkuEsModel; import com.atguigu.gulimall.lsearch.config.GulimallElasticSearchConfig; import com.atguigu.gulimall.lsearch.constant.EsConstant; import com.atguigu.gulimall.lsearch.service.ProductSaveService; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @Slf4j @Service("productSaveService") public class ProductSaveServiceImpl implements ProductSaveService { @Autowired RestHighLevelClient restHighLevelClient; @Override public boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException { //保存到es //1.给es中建立索引。product,建立好映射关系 //2.给es中保存数据 BulkRequest bulkRequest, RequestOptions options BulkRequest bulkRequest = new BulkRequest(); for (SkuEsModel model : skuEsModels) { //构造保存请求 IndexRequest indexRequest = new IndexRequest(EsConstant.PRODUCT_INDEX); indexRequest.id(model.getSkuId().toString()); String s = JSON.toJSONString(model); indexRequest.source(s, XContentType.JSON); bulkRequest.add(indexRequest); } BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, GulimallElasticSearchConfig.COMMON_OPTIONS); //TODO 如果批量保存错误则需要处理 boolean b = bulk.hasFailures(); List<String> collect = Arrays.stream(bulk.getItems()).map(item -> { return item.getId(); }).collect(Collectors.toList()); log.info("商品上架成功:{}，返回数据:{}", collect,bulk.toString()); return b; } }4.Controller类package com.atguigu.gulimall.lsearch.controller; import com.atguigu.common.exception.BizCodeEnume; import com.atguigu.common.to.es.SkuEsModel; import com.atguigu.common.utils.R; import com.atguigu.gulimall.lsearch.service.ProductSaveService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @Slf4j @RequestMapping("/search/save") @RestController public class ElasticSaveController { @Autowired ProductSaveService productSaveService; @PostMapping("/product") public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels) { boolean b = false; try { b = productSaveService.productStatusUp(skuEsModels); } catch (Exception e) { log.error("ElasticSaveController商品商家错误:{}", e); return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMessage()); } if (!b) { return R.ok(); } else { return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMessage()); } } }5.BizCodeEnume枚举package com.atguigu.common.exception; /** * @Description: 错误状态码枚举 * @Created: with IntelliJ IDEA. * @author: 夏沫止水 * @createTime: 2020-05-27 17:29 * * 错误码和错误信息定义类 * 1. 错误码定义规则为5为数字 * 2. 前两位表示业务场景，最后三位表示错误码。例如：100001。10:通用 001:系统未知异常 * 3. 维护错误码后需要维护错误描述，将他们定义为枚举形式 * 错误码列表： * 10: 通用 * 001：参数格式校验 * 002：短信验证码频率太高 * 11: 商品 * 12: 订单 * 13: 购物车 * 14: 物流 * 15：用户 **/ public enum BizCodeEnume { UNKNOW_EXCEPTION(10000, "系统未知异常"), VAILD_EXCEPTION(10001, "参数格式校验失败"), TO_MANY_REQUEST(10002, "请求流量过大，请稍后再试"), SMS_CODE_EXCEPTION(10002, "验证码获取频率太高，请稍后再试"), PRODUCT_UP_EXCEPTION(11000, "商品上架异常"), USER_EXIST_EXCEPTION(15001, "存在相同的用户"), PHONE_EXIST_EXCEPTION(15002, "存在相同的手机号"), NO_STOCK_EXCEPTION(21000, "商品库存不足"), LOGINACCT_PASSWORD_EXCEPTION(15003, "账号或密码错误"), ; private Integer code; private String message; BizCodeEnume(Integer code, String message) { this.code = code; this.message = message; } public Integer getCode() { return code; } public String getMessage() { return message; } }6.其他测试功能package com.atguigu.gulimall.lsearch; import com.alibaba.fastjson.JSON; import com.atguigu.gulimall.lsearch.config.GulimallElasticSearchConfig; import lombok.Data; import lombok.ToString; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.Avg; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import java.util.Map; @SpringBootTest public class GulimallSearchApplicationTests { @Autowired private RestHighLevelClient client; /** * 测试复杂查询功能 */ @Test public void searchDate() throws IOException { //1.创建检索请求 SearchRequest searchRequest = new SearchRequest(); //指定索引 searchRequest.indices("bank"); //指定DSL，检索条件 //SearchSourceBuilder sourceBuilder 封装的条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //1.1构造检索条件 searchSourceBuilder.query(); searchSourceBuilder.from(); searchSourceBuilder.size(); searchSourceBuilder.aggregation(); searchSourceBuilder.query(QueryBuilders.matchQuery("address", "mill")); //1.2按照年龄的值分布进行聚合 TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10); searchSourceBuilder.aggregation(ageAgg); //1.3计算平均薪资 TermsAggregationBuilder balanceAvg = AggregationBuilders.terms("balanceAvg").field("balance"); searchSourceBuilder.aggregation(balanceAvg); System.out.println("检索条件" + searchSourceBuilder.toString()); searchRequest.source(searchSourceBuilder); //2.执行检索 SearchResponse searchResponce = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS); //3.分析结果 System.out.println(searchResponce.toString()); //Map map = JSON.parseObject(searchResponce.toString(), Map.class); 这种方式太麻烦 //3.1获取所有查询到的数据 SearchHits hits = searchResponce.getHits(); SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) { String sourceAsString = hit.getSourceAsString(); Account account = JSON.parseObject(sourceAsString, Account.class); System.out.println("account" + account); } //3.2获取这次检索到的分析信息 Aggregations aggregations = searchResponce.getAggregations(); Terms ageAgg1 = aggregations.get("ageAgg"); for (Terms.Bucket bucket : ageAgg1.getBuckets()) { String keyAsString = bucket.getKeyAsString(); System.out.println("年龄" + keyAsString + "===>" + bucket.getDocCount()); } Avg balanceAvg1 = aggregations.get("balanceAvg"); System.out.println("平均工资" + balanceAvg1.getValue()); } @ToString @Data static class Account { private int account_number; private int balance; private String firstname; private String lastname; private int age; private String gender; private String address; private String employer; private String email; private String city; private String state; } /** * 测试存储数据到es,保存更新二合一 */ @Test public void indexDate() throws IOException { IndexRequest indexRequest = new IndexRequest("users"); //数据的id indexRequest.id("1"); // indexRequest.source("userName", "youzi", "age", 18); User user = new User(); user.setUserName("Youzi"); user.setAge(28); user.setGender("男"); String jsonString = JSON.toJSONString(user); //要保存的内容 indexRequest.source(jsonString, XContentType.JSON); //执行index操作 IndexResponse index = client.index(indexRequest, GulimallElasticSearchConfig.COMMON_OPTIONS); //提取有用的响应数据 System.out.println(index); } @Data class User { private String userName; private String gender; private int age; } }7.工具类package com.atguigu.gulimall.lsearch.config; import org.apache.http.HttpHost; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 1.导入配置 * 2.编写配置,给容器内注入一个RestHighLevelClient */ @Configuration public class GulimallElasticSearchConfig { @Bean public RestHighLevelClient esRestClient() { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( //第一个参数是ElasticSearch安装机地址，第二个参数是端口，第三个参数是协议"http"或"https" new HttpHost("192.168.56.10", 9200, "http") ) ); return client; } public static final RequestOptions COMMON_OPTIONS; static { RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder(); // builder.addHeader("Authorization", "Bearer " + TOKEN); // builder.setHttpAsyncResponseConsumerFactory( // new HttpAsyncResponseConsumerFactory // .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024)); COMMON_OPTIONS = builder.build(); } }
//Fegin的调用流程 /** 1.构造请求数据，将对象转为JSON * RequestTemplate template = buildTemplateFromArgs,create(argv); * 2.发送请求进行执行《执行成功会解码响应数据): * executeAndDecode(template); * 3.执行请求会有重试机制 * while(true){ * try{ * executeAndDecode(template); * }catch(){ * try{retryer.continueOrpropagate(e);}catch()fthrow ex;) * continue; * } * * } */ //位于ReflectiveFeign.class public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!"equals".equals(method.getName())) { //判断如果是hashCode或是toString方法就不需要远程调用 if ("hashCode".equals(method.getName())) { return this.hashCode(); } else { //这里是个三元运算符 return "toString".equals(method.getName()) ? this.toString() : //这里才是真正的远程调用，接下来步入这个方法 ((MethodHandler)this.dispatch.get(method)).invoke(args); } ... } //SynchronousMethodHandler.class 代码演示 public Object invoke(Object[] argv) throws Throwable { //请求模板，包含请求路径、请求方式、请求体等信息 //默认构造的模板是不包含请求头和请求参数的 RequestTemplate template = this.buildTemplateFromArgs.create(argv); Options options = this.findOptions(argv); //这是一个重试器，Feign组件默认使用Ribbon的重试机制并增加了根据状态码判断重试机制。默认是关闭的。 Retryer retryer = this.retryer.clone(); while(true) { try { //真正的执行方法在这 return this.executeAndDecode(template, options); } catch (RetryableException var9) { RetryableException e = var9; try { retryer.continueOrPropagate(e); } catch (RetryableException var8) { Throwable cause = var8.getCause(); if (this.propagationPolicy == ExceptionPropagationPolicy.UNWRAP && cause != null) { throw cause; } throw var8; } if (this.logLevel != Level.NONE) { this.logger.logRetry(this.metadata.configKey(), this.logLevel); } } } }
子页面 父页面 总结：父子组件传递数据子组件给父组件传递数据，事件机制；子组件给父组件发送一个事件，携带上数据。this.$emit("事件名",携带的数据...)
1.安装和原服务器一样的环境1.1我用的是CentOS 系统，首先安装系统环境1.2我使用的是宝塔面板，所以宝塔面板也要安装一致（版本不一致也可以用，不过最好用的是一样的，避免出现未知原因引起的错误）2.迁移前做好备案准备分两种情况在同一个服务器厂商的情况下，只需要把网站的文件迁移到新的服务器（网站文件的路径要和旧服务器的一致）。在不同的服务器厂商的情况下，首先要先进行网站的备案，大概七个工作日，所以不要等到旧服务器快要过期才迁移，这样会导致时间上的不充裕，在迁移过程中会使网站暂停运行，剩下的就是把文件从旧服务器上的文件上传到新的服务器（路径要一致）。3.数据库的迁移在旧服务器上怎么安装的数据库，在新服务器上就怎么安装，最好就是版本都是一样的，然后导出旧数据上的表结构和数据，然后在新服务器上导入，要注意的就是数据库名称和密码要和旧数据库的要一致，这样就方便在新的服务器上运行的时候，不用重新修改代码。4.迁移完成迁移结束后，域名解析要换成新服务器的公网IP，会有缓存，并不是一修改好就马上解析上去的，24-72小时内，所以解析成功后要记得有空看看你的网站能否正常运行。PS1.迁移工具在宝塔面板有一个这个工具，我测试了一下，也是可以迁移成功的2.迁移时图床出现的问题我在迁移过程中是没有发现什么问题，主要是我自己的两个图床工具突然就是上传失败了，完全不能用，报错信息是Call to undefined function think\finfo open()，主要是php中的一个拓展没有安装。2.1找到这个2.2在设置里找到fileinfo并安装2.3重新测试