当前位置: 首页 > 编程日记 > 正文

Solr初始化源码分析-Solr初始化与启动

用solr做项目已经有一年有余,但都是使用层面,只是利用solr现有机制,修改参数,然后监控调优,从没有对solr进行源码级别的研究。但是,最近手头的一个项目,让我感觉必须把solrn内部原理和扩展机制弄熟,才能把这个项目做好。今天分享的就是:Solr是如何启动并且初始化的。大家知道,部署solr时,分两部分:一、solr的配置文件。二、solr相关的程序、插件、依赖lucene相关的jar包、日志方面的jar。因此,在研究solr也可以顺着这个思路:加载配置文件、初始化各个core、初始化各个core中的requesthandler...

研究solr的启动,首先从solr war程序的web.xml分析开始,下面是solr的web.xml片段:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"metadata-complete="true"
><!-- Uncomment if you are trying to use a Resin version before 3.0.19.Their XML implementation isn't entirely compatible with Xerces.Below are the implementations to use with Sun's JVM.<system-property javax.xml.xpath.XPathFactory="com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl"/><system-property javax.xml.parsers.DocumentBuilderFactory="com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"/><system-property javax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"/>--><!-- People who want to hardcode their "Solr Home" directly into theWAR File can set the JNDI property here...--><!--  Solr配置文件的参数,用于Solr初始化使用  --><env-entry><env-entry-name>solr/home</env-entry-name><env-entry-value>R:/solrhome1/solr</env-entry-value><env-entry-type>java.lang.String</env-entry-type></env-entry><!-- org.apache.solr.servlet.SolrDispatchFilter  Solr启动最重要的东东,所以针对solr源码分析,要对这个Filter开始,它主要的作用:加载solr配置文件、初始化各个core、初始化各个requestHandler和component --><filter><filter-name>SolrRequestFilter</filter-name><filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class><!-- If you are wiring Solr into a larger web application which controlsthe web context root, you will probably want to mount Solr undera path prefix (app.war with /app/solr mounted into it, for example).You will need to put this prefix in front of the SolrDispatchFilterurl-pattern mapping too (/solr/*), and also on any paths forlegacy Solr servlet mappings you may be using.For the Admin UI to work properly in a path-prefixed configuration,the admin folder containing the resources needs to be under the app context rootnamed to match the path-prefix.  For example:.warxxxjsmain.js--><!--<init-param><param-name>path-prefix</param-name><param-value>/xxx</param-value></init-param>--></filter>

SolrDispatchFilter 是继承BaseSolrFilter的一个Filter(Filter的作用是啥,大家应该清楚吧,一般web框架级别的产品源码分析都是从filter或者servlet开始)。在介绍SolrDispatchFilter之前,先介绍一下BaseSolrFilter(也许程序员都有刨根问底的习惯)。BaseSolrFilter,是一个实现Filter接口的抽象类,功能很简单,就是判断当前程序是否已经加载日志方面的jar。代码片段如下:

/*** All Solr filters available to the user's webapp should* extend this class and not just implement {@link Filter}.* This class ensures that the logging configuration is correct* before any Solr specific code is executed.*/
abstract class BaseSolrFilter implements Filter {static {//CheckLoggingConfiguration.check();}}

着于篇幅,我就不介绍CheckLoggingConfiguration.check() 这里面的东东了。OK,我们回到SolrDispatchFilter上。由于BaseSolrFilter是一个抽象类,所有作为非抽象类的SolrDispatchFilter必须要实现Filter接口。Filter接口如下:

public interface Filter {//进行初始化public void init(FilterConfig filterConfig) throws ServletException;//拦截所有的http请求public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)throws IOException, ServletException;//进行注销的动作public void destroy();
}

根据上面的注释,我们知道在init方法中是进行初始化的。因此,今天咱们研究SolrDispatchFilter是如何初始化,是离不开这个方法的。接下来,咱们看看SolrDispatchFilter的init方法吧:

  @Overridepublic void init(FilterConfig config) throws ServletException{log.info("SolrDispatchFilter.init()");try {// web.xml configurationthis.pathPrefix = config.getInitParameter( "path-prefix" );//各位看客,乾坤尽在此方法中this.cores = createCoreContainer();log.info("user.dir=" + System.getProperty("user.dir"));}catch( Throwable t ) {// catch this so our filter still workslog.error( "Could not start Solr. Check solr/home property and the logs");SolrCore.log( t );if (t instanceof Error) {throw (Error) t;}}log.info("SolrDispatchFilter.init() done");}

咱们顺藤摸瓜,来看看createCoreContainer这个方法到底干了些什么。

  protected CoreContainer createCoreContainer() {
  //看好了SolrResourceLoader 是用来加载solr home中的配置文件文件的 SolrResourceLoader loader = new SolrResourceLoader(SolrResourceLoader.locateSolrHome());//加载配置文件
ConfigSolr config = loadConfigSolr(loader);CoreContainer cores = new CoreContainer(loader, config);
   //初始化Core cores.load();return cores;}

createCoreContainer这个方法是决定咱们今天能否弄懂Solr初始化和启动的关键。我们顺便简单分析一下这个方法中用到的几个类和方法:

SolrResourceLoader  类如其名,是solr资源加载器。

ConfigSolr 是通过SolrResourceLoader来读取solr配置文件的中信息的。

loadConfigSolr,加载配置信息的方法:

  private ConfigSolr loadConfigSolr(SolrResourceLoader loader) {//优先读取solr.solrxml.location配置的信息,往往是通过读取zookeeper中的配置信息进行初始化的,如果没有配置,就会读取solrhome配置项配置的信息(记得web.xml第一个配置项否,就是它)String solrxmlLocation = System.getProperty("solr.solrxml.location", "solrhome");if (solrxmlLocation == null || "solrhome".equalsIgnoreCase(solrxmlLocation))return ConfigSolr.fromSolrHome(loader, loader.getInstanceDir());//ok 从zookeeper中读取配置信息吧,这是在solrcloud集群下用来solr初始化的if ("zookeeper".equalsIgnoreCase(solrxmlLocation)) {String zkHost = System.getProperty("zkHost");log.info("Trying to read solr.xml from " + zkHost);if (StringUtils.isEmpty(zkHost))throw new SolrException(ErrorCode.SERVER_ERROR,"Could not load solr.xml from zookeeper: zkHost system property not set");SolrZkClient zkClient = new SolrZkClient(zkHost, 30000);try {if (!zkClient.exists("/solr.xml", true))//solr.xml里有描述的zookeeper相关的配置信息throw new SolrException(ErrorCode.SERVER_ERROR, "Could not load solr.xml from zookeeper: node not found");byte[] data = zkClient.getData("/solr.xml", null, null, true);
//加载配置信息return ConfigSolr.fromInputStream(loader, new ByteArrayInputStream(data));} catch (Exception e) {throw new SolrException(ErrorCode.SERVER_ERROR, "Could not load solr.xml from zookeeper", e);} finally {zkClient.close();//关闭zookeeper连接}}throw new SolrException(ErrorCode.SERVER_ERROR,"Bad solr.solrxml.location set: " + solrxmlLocation + " - should be 'solrhome' or 'zookeeper'");}

CoreContainer  就是进行Core初始化工作的。我们主要看看load方法吧,这段方法有点长,代码如下:

public void load()  {log.info("Loading cores into CoreContainer [instanceDir={}]", loader.getInstanceDir());//加载solr共享jar包库// add the sharedLib to the shared resource loader before initializing cfg based pluginsString libDir = cfg.getSharedLibDirectory();if (libDir != null) {File f = FileUtils.resolvePath(new File(solrHome), libDir);log.info("loading shared library: " + f.getAbsolutePath());
//对classloader不熟的,可以进去看看loader.addToClassLoader(libDir, null, false);loader.reloadLuceneSPI();}//分片相关的handler加载以及初始化shardHandlerFactory = ShardHandlerFactory.newInstance(cfg.getShardHandlerFactoryPluginInfo(), loader);updateShardHandler = new UpdateShardHandler(cfg);solrCores.allocateLazyCores(cfg.getTransientCacheSize(), loader);logging = LogWatcher.newRegisteredLogWatcher(cfg.getLogWatcherConfig(), loader);hostName = cfg.getHost();log.info("Host Name: " + hostName);zkSys.initZooKeeper(this, solrHome, cfg);collectionsHandler = createHandler(cfg.getCollectionsHandlerClass(), CollectionsHandler.class);infoHandler = createHandler(cfg.getInfoHandlerClass(), InfoHandler.class);coreAdminHandler = createHandler(cfg.getCoreAdminHandlerClass(), CoreAdminHandler.class);//zookeeper 配置信息初始化solr corecoreConfigService = cfg.createCoreConfigService(loader, zkSys.getZkController());containerProperties = cfg.getSolrProperties("solr");// setup executor to load cores in parallel// do not limit the size of the executor in zk mode since cores may try and wait for each other.
//多线程初始化core 不熟悉多线的可以驻足研究一会ExecutorService coreLoadExecutor = Executors.newFixedThreadPool(( zkSys.getZkController() == null ? cfg.getCoreLoadThreadCount() : Integer.MAX_VALUE ),new DefaultSolrThreadFactory("coreLoadExecutor") );try {CompletionService<SolrCore> completionService = new ExecutorCompletionService<>(coreLoadExecutor);Set<Future<SolrCore>> pending = new HashSet<>();List<CoreDescriptor> cds = coresLocator.discover(this);checkForDuplicateCoreNames(cds);for (final CoreDescriptor cd : cds) {final String name = cd.getName();try {if (cd.isTransient() || ! cd.isLoadOnStartup()) {// Store it away for later use. includes non-transient but not// loaded at startup cores.solrCores.putDynamicDescriptor(name, cd);}if (cd.isLoadOnStartup()) { // The normal caseCallable<SolrCore> task = new Callable<SolrCore>() {@Overridepublic SolrCore call() {SolrCore c = null;try {if (zkSys.getZkController() != null) {//zookeeper模式preRegisterInZk(cd);}c = create(cd);//普通创建模式registerCore(cd.isTransient(), name, c, false, false);} catch (Exception e) {SolrException.log(log, null, e);try {/* if (isZooKeeperAware()) {try {zkSys.zkController.unregister(name, cd);} catch (InterruptedException e2) {Thread.currentThread().interrupt();SolrException.log(log, null, e2);} catch (KeeperException e3) {SolrException.log(log, null, e3);}}*/} finally {if (c != null) {c.close();}} }return c;}};pending.add(completionService.submit(task));}} catch (Exception e) {SolrException.log(log, null, e);}}while (pending != null && pending.size() > 0) {try {//获取创建完成的coreFuture<SolrCore> future = completionService.take();if (future == null) return;pending.remove(future);try {SolrCore c = future.get();// track original namesif (c != null) {solrCores.putCoreToOrigName(c, c.getName());}} catch (ExecutionException e) {SolrException.log(SolrCore.log, "Error loading core", e);}} catch (InterruptedException e) {throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE,"interrupted while loading core", e);}}
//solr core的守护线程,在容器关闭或者启动失败的时候,进行资源注销// Start the background threadbackgroundCloser = new CloserThread(this, solrCores, cfg);backgroundCloser.start();} finally {if (coreLoadExecutor != null) {
//初始化完成,关闭线程池ExecutorUtil.shutdownNowAndAwaitTermination(coreLoadExecutor);}}if (isZooKeeperAware()) {//如果zookeeper可用 也就是solrcloud模式// register in zk in background threadsCollection<SolrCore> cores = getCores();if (cores != null) {for (SolrCore core : cores) {try {
//讲core的状态信息注册到zookeeper中zkSys.registerInZk(core, true);} catch (Throwable t) {SolrException.log(log, "Error registering SolrCore", t);}}}
//zkSys.getZkController().checkOverseerDesignate();}}

在这段代码,关键部分我都做了注释。当你需要优化你的solr启动速度时,你还会来研究这段代码。下面,我们将研究solr的请求过滤处理的部分,我们需要关注doFilter那个方法了(关键部分我作以注释,就不细讲了):

 if( abortErrorMessage != null ) {//500错误处理((HttpServletResponse)response).sendError( 500, abortErrorMessage );return;}if (this.cores == null) {//solr core初始化失败或者已经关闭((HttpServletResponse)response).sendError( 503, "Server is shutting down or failed to initialize" );return;}CoreContainer cores = this.cores;SolrCore core = null;SolrQueryRequest solrReq = null;Aliases aliases = null;if( request instanceof HttpServletRequest) {//如果是http请求HttpServletRequest req = (HttpServletRequest)request;HttpServletResponse resp = (HttpServletResponse)response;SolrRequestHandler handler = null;String corename = "";String origCorename = null;try {// put the core container in request attributereq.setAttribute("org.apache.solr.CoreContainer", cores);String path = req.getServletPath();if( req.getPathInfo() != null ) {// this lets you handle /update/commit when /update is a servletpath += req.getPathInfo();}if( pathPrefix != null && path.startsWith( pathPrefix ) ) {path = path.substring( pathPrefix.length() );}// check for management pathString alternate = cores.getManagementPath();if (alternate != null && path.startsWith(alternate)) {path = path.substring(0, alternate.length());}// unused feature ?int idx = path.indexOf( ':' );if( idx > 0 ) {// save the portion after the ':' for a 'handler' path parameterpath = path.substring( 0, idx );}// Check for the core admin pageif( path.equals( cores.getAdminPath() ) ) {//solr admin 管理页面请求handler = cores.getMultiCoreHandler();solrReq =  SolrRequestParsers.DEFAULT.parse(null,path, req);handleAdminRequest(req, response, handler, solrReq);return;}boolean usingAliases = false;List<String> collectionsList = null;// Check for the core admin collections urlif( path.equals( "/admin/collections" ) ) {//管理collections handler = cores.getCollectionsHandler();solrReq =  SolrRequestParsers.DEFAULT.parse(null,path, req);handleAdminRequest(req, response, handler, solrReq);return;}// Check for the core admin info urlif( path.startsWith( "/admin/info" ) ) {//查看admin infohandler = cores.getInfoHandler();solrReq =  SolrRequestParsers.DEFAULT.parse(null,path, req);handleAdminRequest(req, response, handler, solrReq);return;}else {//otherwise, we should find a core from the pathidx = path.indexOf( "/", 1 );if( idx > 1 ) {// try to get the corename as a request parameter firstcorename = path.substring( 1, idx );// look at aliasesif (cores.isZooKeeperAware()) {//solr cloud状态origCorename = corename;ZkStateReader reader = cores.getZkController().getZkStateReader();aliases = reader.getAliases();if (aliases != null && aliases.collectionAliasSize() > 0) {usingAliases = true;String alias = aliases.getCollectionAlias(corename);if (alias != null) {collectionsList = StrUtils.splitSmart(alias, ",", true);corename = collectionsList.get(0);}}}core = cores.getCore(corename);if (core != null) {path = path.substring( idx );}}if (core == null) {if (!cores.isZooKeeperAware() ) {core = cores.getCore("");}}}if (core == null && cores.isZooKeeperAware()) {// we couldn't find the core - lets make sure a collection was not specified insteadcore = getCoreByCollection(cores, corename, path);if (core != null) {// we found a core, update the pathpath = path.substring( idx );}// if we couldn't find it locally, look on other nodesif (core == null && idx > 0) {String coreUrl = getRemotCoreUrl(cores, corename, origCorename);// don't proxy for internal update requestsSolrParams queryParams = SolrRequestParsers.parseQueryString(req.getQueryString());if (coreUrl != null&& queryParams.get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) == null) {path = path.substring(idx);remoteQuery(coreUrl + path, req, solrReq, resp);return;} else {if (!retry) {// we couldn't find a core to work with, try reloading aliases// TODO: it would be nice if admin ui elements skipped this...ZkStateReader reader = cores.getZkController().getZkStateReader();reader.updateAliases();doFilter(request, response, chain, true);return;}}}// try the default coreif (core == null) {core = cores.getCore("");}}// With a valid core...if( core != null ) {//验证corefinal SolrConfig config = core.getSolrConfig();// get or create/cache the parser for the coreSolrRequestParsers parser = config.getRequestParsers();// Handle /schema/* and /config/* paths via Restletif( path.equals("/schema") || path.startsWith("/schema/")|| path.equals("/config") || path.startsWith("/config/")) {//solr rest api 入口  solrReq = parser.parse(core, path, req);SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, new SolrQueryResponse()));if( path.equals(req.getServletPath()) ) {// avoid endless loop - pass through to Restlet via webappchain.doFilter(request, response);} else {// forward rewritten URI (without path prefix and core/collection name) to Restletreq.getRequestDispatcher(path).forward(request, response);}return;}// Determine the handler from the url path if not set// (we might already have selected the cores handler)if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid pathhandler = core.getRequestHandler( path );// no handler yet but allowed to handle select; let's checkif( handler == null && parser.isHandleSelect() ) {if( "/select".equals( path ) || "/select/".equals( path ) ) {//solr 各种查询过滤入口 solrReq = parser.parse( core, path, req );String qt = solrReq.getParams().get( CommonParams.QT );handler = core.getRequestHandler( qt );if( handler == null ) {throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);}if( qt != null && qt.startsWith("/") && (handler instanceof ContentStreamHandlerBase)) {//For security reasons it's a bad idea to allow a leading '/', ex: /select?qt=/update see SOLR-3161//There was no restriction from Solr 1.4 thru 3.5 and it's not supported for update handlers.throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Invalid Request Handler ('qt').  Do not use /select to access: "+qt);}}}}// With a valid handler and a valid core...if( handler != null ) {// if not a /select, create the requestif( solrReq == null ) {solrReq = parser.parse( core, path, req );}if (usingAliases) {processAliases(solrReq, aliases, collectionsList);}final Method reqMethod = Method.getMethod(req.getMethod());HttpCacheHeaderUtil.setCacheControlHeader(config, resp, reqMethod);// unless we have been explicitly told not to, do cache validation// if we fail cache validation, execute the queryif (config.getHttpCachingConfig().isNever304() ||!HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req, reqMethod, resp)) {//solr http 缓存 在header控制失效时间的方式SolrQueryResponse solrRsp = new SolrQueryResponse();/* even for HEAD requests, we need to execute the handler to* ensure we don't get an error (and to make sure the correct* QueryResponseWriter is selected and we get the correct* Content-Type)*/SolrRequestInfo.setRequestInfo(new SolrRequestInfo(solrReq, solrRsp));this.execute( req, handler, solrReq, solrRsp );HttpCacheHeaderUtil.checkHttpCachingVeto(solrRsp, resp, reqMethod);// add info to http headers//TODO: See SOLR-232 and SOLR-267.  /*try {NamedList solrRspHeader = solrRsp.getResponseHeader();for (int i=0; i<solrRspHeader.size(); i++) {((javax.servlet.http.HttpServletResponse) response).addHeader(("Solr-" + solrRspHeader.getName(i)), String.valueOf(solrRspHeader.getVal(i)));}} catch (ClassCastException cce) {log.log(Level.WARNING, "exception adding response header log information", cce);}*/QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);writeResponse(solrRsp, response, responseWriter, solrReq, reqMethod);}return; // we are done with a valid handler}}log.debug("no handler or core retrieved for " + path + ", follow through...");} catch (Throwable ex) {sendError( core, solrReq, request, (HttpServletResponse)response, ex );if (ex instanceof Error) {throw (Error) ex;}return;} finally {try {if (solrReq != null) {log.debug("Closing out SolrRequest: {}", solrReq);solrReq.close();}} finally {try {if (core != null) {core.close();}} finally {SolrRequestInfo.clearRequestInfo();}}}}// Otherwise let the webapp handle the requestchain.doFilter(request, response);}

文章转载请注明出处:http://www.cnblogs.com/likehua/p/4353608.html

转载于:https://www.cnblogs.com/likehua/p/4353608.html

相关文章:

iOS :UIPickerView reloadAllComponets not work

编辑信息页面用了很多选择栏&#xff0c;大部分都用 UIPickerView 来实现。在切换数据显示的时候&#xff0c; UIPickerView 不更新数据&#xff0c;不得其解。Google 无解&#xff0c;原因在于无法描述自己的问题&#xff0c;想想应该还是代码哪里写错了。 写了个测试方法&…

单相计量芯片RN8209D使用经验分享(转)

单相计量芯片RN8209D使用经验分享转载于:https://www.cnblogs.com/LittleTiger/p/10736060.html

git 对之前的commit 进行重新签名 Resign

在向开源社区提交PR的时候如果之前的提交忘记添加sign &#xff08;个人签名/公司签名&#xff09;&#xff0c;则社区的DCO检查会失败。 关于通过DCO检查能够确保以下几件事情生效&#xff1a; 你所提交的贡献是由你自己完成或者 你参与了其中&#xff0c;并且有权利按照开源…

【原创】linux命令bc使用详解

最近经常要在linux下做一些进制转换&#xff0c;看到了可以使用bc命令&#xff0c;如下: echo "obase10;ibase16;CFFF" | bc 用完以后就对bc进行了进一步的了解, man bc里面有详细的使用说明。 1.是什么,怎么用 bc - An arbitrary precision calculator language 一…

Java项目:学生信息管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 用户的登录注册&#xff0c;学生信息管理&#xff0c;教师信息管理&#xff0c;班级信 息管理&#xff0c;采用mvcx项目架构&#xff0c;覆盖增删改查&#xff0c;包括学…

MVC學習網站

http://www.cnblogs.com/haogj/archive/2011/11/23/2246032.html

数据导出Excel表格

public String exportInfoFr(String path,String name,String startdate,String enddate,SysUser user){List<Map<String, Object>> list this.esEntPermitErrDao.findListObjectBySql("select 字段值1,字段值2,字段值3,字段值4,字段值5 from 表名 where 字段…

Rocksdb 通过posix_advise 让内核减少在page_cache的预读

文章目录1. 问题排查确认I/O完全/大多数来自于rocksdb确认此时系统只使用了rocksdb的Get来读确认每次系统调用下发读的请求大小确认是否在内核发生了预读2. 问题原因内核预读机制page_cache_sync_readaheadondemand_readahead3. 优化事情起源于 组内的分布式kv 系统使用rocksdb…

[leetcode] Minimum Path Sum

Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time.分析&#xff1a;动态规划…

Java项目:在线小说阅读系统(读者+作者+管理员)(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 1:用户及主要操作功能 游客可以浏览网站的主页&#xff0c;登陆注册&#xff0c;小说湿度&#xff0c;下单购 买&#xff0c;订单查询&#xff0c;个人信息查询&#xf…

游戏中的脚本语言

本文最初发表于《游戏创造》(http://www.chinagcn.com)2007年8月刊。版权所有&#xff0c;侵权必究。如蒙转载&#xff0c;必须保留本声明&#xff0c;和作者署名&#xff1b;不得用于商业用途&#xff0c;必须保证全文完整。网络版首次发表于恋花蝶的博客(http://blog.csdn.ne…

mvn项目中的pom文件提示Error parsing lifecycle processing instructions解决

清空.m2/repository下的所有依赖文件&#xff0c;重新下载即可解决该问题。 如果本地用户下没有.m2/repository 目录&#xff0c;找到如下mvn 指定的repository&#xff0c;进去之后清空所有文件。 转载于:https://www.cnblogs.com/Hackerman/p/10736498.html

blktrace 工具集使用 及其实现原理

文章目录工具使用原理分析内核I/O栈blktrace 代码做的事情内核调用 ioctl 做的事情BLKTRACESETUPBLKTRACESTOPBLKTRACETEARDOWN内核 调用blk_register_tracepoints 之后做的事情参考最近使用blktrace 工具集来分析I/O 在磁盘上的一些瓶颈问题&#xff0c;特此做一个简单的记录。…

Java项目:教材管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 管理员可以增删改查教材、教材商、入库教材、用户(用 户包括学生和教师)可以对教材商、教材进行。xcel的导入 导出操作。教U阿以领取入库的教材&#xff0c;可以退还教材…

mysql更改数据文件目录及my.ini位置| MySQL命令详解

需求&#xff1a;更改mysql数据数据文件目录及my.ini位置。 步骤&#xff1a; 1、查找my.ini位置&#xff0c;可通过windows服务所对应mysql启动项&#xff0c;查看其对应属性->可执行文件路径&#xff0c;获取my.ini路径。 "D:\MySQL\MySQL Server 5.5\bin\mysqld&quo…

私有云管理-Windows Azure Pack

今天是2014年的第一天&#xff0c;今年的第一篇博客关于私有云&#xff0c;而我在2014年的主要目标也是针对私有云。随着Windows Azure在中国的落地&#xff0c;大家逐渐的熟悉了在Windows Azure中的云体验。而微软针对私有云、混合云推出了一个管理自助门户&#xff0c;Window…

面向对象(类的概念,属性,方法,属性的声明,面向对象编程思维

1 面向对象 1.1 你是如何认识新事物的&#xff1f; 从过往的事物中总结事物的特点(特征)&#xff0c;并比对新事物&#xff0c;把新事物进行归类。 1.2 类(Class)的概念(A) 类是对一组具有相同特征和行为的对象的抽象描述。 理解: [1] 类包含了两个要素:特性和行为 > 同一类…

cannot find main module 解决办法

做6.824 实验的过程中想要跑测试&#xff0c;发现go test -run 2A时 出现cannot find main module问题&#xff0c;测试跑不起来。 原因 这个原因是从GO1.11 版本开始引入了go.mod文件来对项目中的go源码的编译相关的内容进行管理&#xff0c;经常使用GO的同学可能深受go get…

Java项目:网上选课系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a; 系统分为三个角色。最高权限管理员&#xff0c;学生&#xff0c;教师&#xff0c;包括 学生管理&#xff0c;教师管理&#xff0c;课程管理&#xff0c;选课&#xff0c;退课…

C#中类的继承 override virtual new的作用以及代码分析

继承中override virtual new的作用 virtual 父类中需要注明允许重写的方法&#xff1b; override 子类中必须显示声明该方法是重写的父类中的方法&#xff1b; new 子类中忽略父类的已存在的方法&#xff0c;“重写该方法“&#xff1b; C#中不支…

spring手动代码控制事务

为什么80%的码农都做不了架构师&#xff1f;>>> DataSourceTransactionManager tran new DataSourceTransactionManager(vjdbcTemplate.getDataSource());DefaultTransactionDefinition def new DefaultTransactionDefinition();//事务定义类def.setPropagationB…

tar命令-压缩,解压缩文件

tar&#xff1a; -c: 建立压缩档案 -x&#xff1a;解压 -t&#xff1a;查看内容 -r&#xff1a;向压缩归档文件末尾追加文件 -u&#xff1a;更新原压缩包中的文件 上面五个参数是独立的&#xff0c;压缩解压都要用到其中一个&#xff0c;可以和下面的命令连用但只能用其中一个。…

MIT 6.824 Lab2A (raft) -- Leader Election

文章目录实验要求Leader Election流程 及详细实现介绍基本角色关键超时变量关键的两个RPC实现RequestVote RPCAppendEntries RPCGo并发编程实现leader election调度本节记录的是完成MIT6.824 raft lab的leader Election部分实验。代码: https://github.com/BaronStack/MIT-6.82…

Java项目:在线考试系统(java+springboot+vue+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统主要实现的功能有&#xff1a; 学生以及老师的注册登录&#xff0c;在线考试&#xff0c;错题查询&#xff0c;学生管理&#xff0c;问题管理&#xff0c;错题管理&#xff0c;错题查询…

写给自己的web开发资源

web开发给我的感觉就是乱七八糟&#xff0c;而且要学习感觉总是会有东西要学习&#xff0c;很乱很杂我也没空搞&#xff0c;&#xff08;其实学习这个的方法就是去用它&#xff0c;什么你直接用&#xff1f;学过js么学过jquery么&#xff1f;哈哈&#xff0c;我没有系统的看完过…

虚拟机VMWare“提示:软件虚拟化与此平台上的长模式不兼容”的解决方法

虚拟机VMWare“提示&#xff1a;软件虚拟化与此平台上的长模式不兼容”不少童鞋反映&#xff0c;在使用Windows7 64位操作系统时&#xff0c;无法运行VMWare或MS Virtual server等软件虚拟操作系统。提示为“提示&#xff1a;软件虚拟化与此平台上的长模式不兼容. 禁用长模式. …

如何在Vue项目中使用vw实现移动端适配(转)

有关于移动端的适配布局一直以来都是众说纷纭&#xff0c;对应的解决方案也是有很多种。在《使用Flexible实现手淘H5页面的终端适配》提出了Flexible的布局方案&#xff0c;随着viewport单位越来越受到众多浏览器的支持&#xff0c;因此在《再聊移动端页面的适配》一文中提出了…

Jsoncpp 在C++开发中的一些使用记录

jsoncpp 是一个C 语言实现的json库&#xff0c;非常方便得支持C得各种数据类型到json 以及 json到各种数据类型的转化。 一个json 类型的数据如下&#xff1a; {"code" : 10.01,"files" : "","msg" : "","uploadid&q…

Java项目:图书管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括(管理员和学生角色)&#xff1a; 管理员和学生登录&#xff0c;图书管理&#xff0c;图书添加删除修改&#xff0c;图书 借阅&#xff0c;图书归还&#xff0c;图书查看&#xff0c;学…

使用 Flash Builder 的 Apple iOS 开发过程

使用 Flash Builder 的 Apple iOS 开发过程 iOS 开发和部署过程概述 构建、调试或部署 iOS 应用程序前的准备工作 在测试、调试或安装 iOS 应用程序时选择的文件 将应用程序部署到 Apple App Store 时选择的文件 在使用 Flash Builder 开发 iOS 应用程序之前&#xff0c;必须…